package cqrtplm.service.impl;import cn.hutool.core.collection.CollUtil;import cn.hutool.core.collection.ListUtil;import cn.hutool.core.util.ObjectUtil;import cn.hutool.poi.excel.ExcelReader;import cn.hutool.poi.excel.ExcelUtil;import cn.hutool.poi.excel.ExcelWriter;import com.alibaba.cloud.commons.lang.StringUtils;import com.alibaba.excel.EasyExcel;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;import com.hustcad.plm.caddoc.mapper.TyplmCADDescribeLinkMapper;import com.hustcad.plm.caddoc.mapper.TyplmCADDocMasterMapper;import com.hustcad.plm.caddocapi.service.TyplmCADDocumentService;import com.hustcad.plm.derivedimage.service.TyplmDerivedImageService;import com.hustcad.plm.derivedimage.vo.DerivedImageVO;import com.hustcad.plm.lightweight.dto.DerivedImageDTO;import com.hustcad.plm.lightweight.dto.LightWeightAgainDTO;import com.hustcad.plm.lightweight.service.TyplmLightweightAgainService;import com.hustcad.plm.middle.caddocapi.service.TyplmImportDwgService;import com.hustcad.plm.pdm.caddoc.model.vo.CADContentDataVO;import com.hustcad.plm.pdm.caddoc.model.vo.MDAImportOutDocVo;import com.hustcad.plm.pdm.classification.model.dto.TyplmClassificationEntityDTO;import com.hustcad.plm.pdm.classification.model.dto.TyplmClassificationRelentityDTO;import com.hustcad.plm.pdm.classification.service.TyplmClassificationRootService;import com.hustcad.plm.pdm.classification.service.TyplmClassificationService;import com.hustcad.plm.pdm.common.model.vo.BusinessObjectVO;import com.hustcad.plm.pdm.common.model.vo.tableview.inittableview.PartAttrsVO;import com.hustcad.plm.pdm.common.util.CommonUtil;import com.hustcad.plm.pdm.constraint.model.dto.TyplmConstraintQueryDTO;import com.hustcad.plm.pdm.constraint.model.vo.TyplmConstraintEditVO;import com.hustcad.plm.pdm.constraint.model.vo.TyplmConstraintRuleDefVO;import com.hustcad.plm.pdm.constraint.service.TyplmConstraintExtService;import com.hustcad.plm.pdm.container.mapper.TyplmPdmLinkProductMapper;import com.hustcad.plm.pdm.container.model.dto.Product;import com.hustcad.plm.pdm.container.service.ProductService;import com.hustcad.plm.pdm.doc.dto.CreateDocInputDTO;import com.hustcad.plm.pdm.doc.dto.SaveDocDTO;import com.hustcad.plm.pdm.doc.service.TyplmDocumentService;import com.hustcad.plm.pdm.doc.vo.DocDetails;import com.hustcad.plm.pdm.doc.vo.DocumentVO;import com.hustcad.plm.pdm.enumeration.model.dto.HandleEnumItemDTO;import com.hustcad.plm.pdm.enumeration.model.vo.EnumerationItemHandleVO;import com.hustcad.plm.pdm.enumeration.service.TyplmEnumerationItemService;import com.hustcad.plm.pdm.enumeration.service.TyplmEnumerationService;import com.hustcad.plm.pdm.file.model.dto.BatchUploadDTO;import com.hustcad.plm.pdm.file.model.dto.ContentUploadDTO;import com.hustcad.plm.pdm.file.model.dto.FileGroupDTO;import com.hustcad.plm.pdm.file.service.TyplmFileHandleService;import com.hustcad.plm.pdm.filevault.model.vo.FileDataVO;import com.hustcad.plm.pdm.folder.mapper.TyplmSubfolderMapper;import com.hustcad.plm.pdm.folder.model.dto.HyperlinkDTO;import com.hustcad.plm.pdm.folder.model.dto.QuerySubFolderOutDTO;import com.hustcad.plm.pdm.folder.model.vo.SubfolderVO;import com.hustcad.plm.pdm.folder.model.vo.SubfolderWebVO;import com.hustcad.plm.pdm.folder.service.TyplmHyperlinkService;import com.hustcad.plm.pdm.folder.service.TyplmSubFolderLinkService;import com.hustcad.plm.pdm.iba.mapper.TyplmStringDefMapper;import com.hustcad.plm.pdm.iba.model.dto.AttributeDefDTO;import com.hustcad.plm.pdm.iba.model.dto.SaveObjIBADTO;import com.hustcad.plm.pdm.iba.service.TyplmAttributeDefService;import com.hustcad.plm.pdm.iba.service.TyplmAttributeService;import com.hustcad.plm.pdm.iba.service.TyplmAttributeValueService;import com.hustcad.plm.pdm.lifestage.service.TyplmLifecycleTemplateService;import com.hustcad.plm.pdm.middle.caddoc.model.dto.Import2dDocForTsDTO;import com.hustcad.plm.pdm.middle.caddoc.model.dto.InsertCadDocDTO;import com.hustcad.plm.pdm.middle.partbom.adapter.TyplmPartBomAdapter;import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartRelObjectService;import com.hustcad.plm.pdm.middle.partbom.service.TyplmPdmPartService;import com.hustcad.plm.pdm.partbom.dto.PartBomTreeNode;import com.hustcad.plm.pdm.partbom.dto.PartBomView;import com.hustcad.plm.pdm.partbom.dto.PartLinkCadDTO;import com.hustcad.plm.pdm.partbom.service.TyplmPartRelObjectService;import com.hustcad.plm.pdm.partbom.service.TyplmPartUsageLinkService;import com.hustcad.plm.pdm.partbom.service.view.TyplmViewDefService;import com.hustcad.plm.pdm.partbom.vo.PdmPartInfoVO;import com.hustcad.plm.pdm.type.service.TyplmTypeService;import com.hustcad.plm.workspace.service.TyPlmWorkspaceObjectService;import com.hustcad.plm.workspace.vo.ObjNumberErrorVO;import com.ty.basic.constant.TableTypeConstrant;import com.ty.basic.dto.constraint.IbaDTO;import com.ty.basic.entity.CTyEntityBaseDO;import com.ty.basic.entity.IdentifierEntity;import com.ty.basic.entity.cad.CADDocDO;import com.ty.basic.entity.cad.CADDocMasterDO;import com.ty.basic.entity.enumeration.EnumerationDefDO;import com.ty.basic.entity.folder.SubfolderDO;import com.ty.basic.entity.lifecycle.LifeCycleTemplateDO;import com.ty.basic.entity.org.UserDO;import com.ty.basic.entity.part.PartDO;import com.ty.basic.entity.product.PdmLinkProductDO;import com.ty.basic.entity.type.ClassificationDO;import com.ty.basic.entity.view.ViewDefDO;import com.ty.basic.exception.message.SystemErrorCodeEnum;import com.ty.basic.session.RequestContext;import com.ty.basic.session.TyAccountContext;import com.ty.basic.utils.BatchQueryHelper;import com.ty.basic.vo.AttributeVO;import com.ty.basic.vo.TyAttributeDefMapVO;import cqrtplm.adapter.DataTransAdapter;import cqrtplm.common.CommonService;import cqrtplm.config.ProcessDocumentConfig;import cqrtplm.constant.RTErrorCodeEnum;import cqrtplm.dto.*;import cqrtplm.entity.DescribeSpliceRuleDO;import cqrtplm.entity.ImportEbomCodeDTO;import cqrtplm.mapper.ProjectDevOrderMapper;import cqrtplm.mapper.RTClassificationMapper;import cqrtplm.mapper.RTEnumMapper;import cqrtplm.mapper.RTPartMapper;import cqrtplm.mapper.RTTypeClassMapper;import cqrtplm.service.HistoryDataImportService;import cqrtplm.service.RTAttributeCardService;import cqrtplm.service.RTClassificationService;import cqrtplm.service.TyEnumerationdefService;import cqrtplm.util.FTPUtil;import lombok.extern.slf4j.Slf4j;import org.apache.commons.net.ftp.FTPClient;import org.apache.commons.net.ftp.FTPReply;import org.apache.poi.ss.usermodel.Cell;import org.apache.poi.ss.usermodel.CellType;import org.apache.poi.ss.usermodel.DateUtil;import org.apache.poi.ss.usermodel.FormulaEvaluator;import org.dom4j.Document;import org.dom4j.DocumentHelper;import org.dom4j.Element;import org.jetbrains.annotations.NotNull;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.beans.factory.annotation.Value;import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;import org.springframework.mock.web.MockMultipartFile;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import org.springframework.web.multipart.MultipartFile;import tk.mybatis.mapper.entity.Example;import javax.annotation.Resource;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.math.BigDecimal;import java.math.BigInteger;import java.net.URLEncoder;import java.nio.charset.StandardCharsets;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.*;import java.util.concurrent.CompletableFuture;import java.util.function.Function;import java.util.stream.Collectors;import java.util.stream.IntStream;@Service@Slf4j@Transactional(rollbackFor = Exception.class)public class HistoryDataImportServiceImpl implements HistoryDataImportService {    private BigInteger lifeCycleTemplateOid;    private static final FTPClient ftpClient = new FTPClient();    private static final String DESIGN = "Design";    private static final String YES = "Y";    private final static String THREE = "UGMASTER";    private final static String DWG = "DWG";    private final static String UG = "UG";    private static int ID = 1;    private static int IDENTIFIER = 1;    @Value("${zc.folderPath.draw:设计图纸}")    private String productName;    @Value("${zc.folderPath.draw:设计图纸}")    private String drawFolder;    @Resource    private TyPlmWorkspaceObjectService tyPlmWorkSpaceObjectService;    @Resource    private TyplmPdmPartService typlmPdmPartService;    @Resource    private RTPartMapper rtPartMapper;    @Resource    private ProjectDevOrderMapper projectDevOrderMapper;    @Resource    private TyplmHyperlinkService typlmHyperlinkService;    @Resource    private TyplmSubFolderLinkService typlmSubFolderLinkService;    @Resource    private TyplmLifecycleTemplateService typlmLifecycleTemplateService;    @Resource    private TyplmTypeService typlmTypeService;    @Resource    private TyplmDocumentService typlmDocumentService;    @Resource    private TyplmClassificationService typlmClassificationService;    @Resource    private TyplmPdmLinkProductMapper typlmPdmLinkProductMapper;    @Resource    private DataTransAdapter dataTransAdapter;    @Resource    private ProductService productService;    @Resource    private TyplmPartRelObjectService typlmPartRelObjectService;    @Resource    private TyplmCADDescribeLinkMapper typlmCADDescribeLinkMapper;    @Resource    private TyplmPdmPartRelObjectService typlmPdmPartRelObjectService;    @Resource    private TyplmDerivedImageService typlmDerivedImageService;    @Resource    private TyplmAttributeValueService typlmAttributeValueService;    @Resource    private TyplmSubfolderMapper typlmSubfolderMapper;    @Resource    private TyplmConstraintExtService typlmConstraintExtService;    @Resource    private TyplmEnumerationItemService typlmEnumerationItemService;    @Resource    private TyplmPartUsageLinkService typlmPartUsageLinkService;    @Resource    private TyplmViewDefService typlmViewDefService;    @Resource    private TyplmPartBomAdapter typlmPartBomAdapter;    @Resource    TyplmLightweightAgainService typlmLightweightAgainService;    @Resource    private TyplmCADDocMasterMapper tyCadDocMasterMapper;    @Resource    private TyplmCADDocumentService tyCadDocumentService;    @Resource    private TyplmFileHandleService fileHandleService;    @Resource    private TyplmImportDwgService typlmImportDwgService;    @Resource    private TyplmAttributeService typlmAttributeService;    @Resource    private RTTypeClassMapper rtTypeClassMapper;    @Resource    private RTEnumMapper enumMapper;    @Autowired    private FTPUtil fTPUtil;    @Value("${file.ftp.ip:192.168.102.190}")    private String fileFtpIp;    @Value("${file.ftp.port:921}")    private String fileFtpPort;    @Value("${file.ftp.user:typlm}")    private String fileFtpUser;    @Value("${file.ftp.password:ty#123456}")    private String fileFtpPassword;    @Resource    private CommonService commonService;    @Resource    private TyplmStringDefMapper typlmStringDefMapper;    @Qualifier("getMappingJackson2HttpMessageConverter")    @Autowired    private MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter;    @Autowired    private CategoryPictureServiceImpl categoryPictureServiceImpl;    @Override    public void updateEnum(MultipartFile file) {        List<ImportPatternCodeDTO> dataList = new ArrayList<>();        try {            dataList = EasyExcel.read(file.getInputStream(), ImportPatternCodeDTO.class,                                      null)                    .sheet()                    .doReadSync();        } catch (Exception e) {            log.error("Excel文件读取失败", e);        }        Map<String, List<ClassInfoDTO>> classInfoDTOMap = new HashMap<>();        List<List<ImportPatternCodeDTO>> dataListList = CommonUtil.subObjectList(dataList, 999);        Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap = new HashMap<>();        Map<BigInteger, List<EnumerationItemHandleVO>> allParentEnumItemMap = new HashMap<>();        for (List<ImportPatternCodeDTO> importPatternCodeDTOS : dataListList) {            List<String> classificationList = importPatternCodeDTOS.stream().map(                            item -> item.getCodeType() + "_" + item.getCardName())                    .distinct().collect(Collectors.toList());            Set<BigInteger> classIds = typlmClassificationService.batchQueryClassificationByNameList(classificationList)                    .stream().map(ClassificationDO::getOid).collect(Collectors.toSet());            List<ClassInfoDTO> classInfoDTOList = rtTypeClassMapper.selectClassInfoByClassId(ListUtil.toList(classIds));            Map<String, List<ClassInfoDTO>> classInfoDTOS = classInfoDTOList.stream().collect(                    Collectors.groupingBy(ClassInfoDTO::getClassName, LinkedHashMap::new, Collectors.toList()));            if (CollUtil.isNotEmpty(classInfoDTOS)) {                classInfoDTOMap.putAll(classInfoDTOS);            }            List<List<ClassInfoDTO>> classInfoListList = CommonUtil.subObjectList(classInfoDTOList, 999);            for (List<ClassInfoDTO> classInfoList : classInfoListList) {                Set<String> childEnumIdList = classInfoList.stream().map(ClassInfoDTO::getChildEnumOid).collect(                        Collectors.toSet());                List<EnumerationItemHandleVO> childEnumItemList = enumMapper.batchSelectEnumByEnumId(                        ListUtil.toList(childEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> childEnumItemMap = childEnumItemList.stream().collect(                        Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if (CollUtil.isNotEmpty(childEnumItemMap)) {                    allChildEnumItemMap.putAll(childEnumItemMap);                }                Set<String> parentEnumIdList = classInfoList.stream().map(ClassInfoDTO::getParentEnumOid).collect(                        Collectors.toSet());                List<EnumerationItemHandleVO> parentEnumItemList = enumMapper.batchSelectEnumByEnumId(                        ListUtil.toList(parentEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> parentEnumItemMap = parentEnumItemList.stream().collect(                        Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if (CollUtil.isNotEmpty(parentEnumItemMap)) {                    allParentEnumItemMap.putAll(parentEnumItemMap);                }            }        }        for (ImportPatternCodeDTO dto : dataList) {            if (!classInfoDTOMap.containsKey(dto.getCodeType() + "_" + dto.getCardName())) {                continue;            }            List<String> ibaAttrValue = Arrays.asList(dto.getIbaAttrValue().split(";;;"));            List<String> ibaAttrName = Arrays.asList(dto.getIbaAttrName().split(";;;"));            if (areAllListsEqualSizeStream(ibaAttrValue, ibaAttrName)) {                List<ClassInfoDTO> classInfoDTOS = classInfoDTOMap.get(dto.getCodeType() + "_" + dto.getCardName());                Map<String, String> describeRuleDTOS = new HashMap<>();                for (int i = 0; i < ibaAttrValue.size(); i++) {                    describeRuleDTOS.put(ibaAttrName.get(i), ibaAttrValue.get(i));                }                for (ClassInfoDTO classInfoDTO : classInfoDTOS) {                    String attributeDisName = classInfoDTO.getAttributeDisName();                    if(describeRuleDTOS.containsKey(attributeDisName)){                        String value = describeRuleDTOS.get(attributeDisName);                        if(StringUtils.isEmpty(value) || StringUtils.isBlank(value)){                            continue;                        }                        String childEnumOid = classInfoDTO.getChildEnumOid();                        String parentEnumOid = classInfoDTO.getParentEnumOid();                        IdentifierEntity childEnum = new IdentifierEntity();                        childEnum.setOid(new BigInteger(childEnumOid));                        childEnum.setOtype(TableTypeConstrant.CTYOBJECTIDENTIFIER);                        List<EnumerationItemHandleVO> childEnumItems;                        if(allChildEnumItemMap.containsKey(new BigInteger(childEnumOid))){                            childEnumItems = allChildEnumItemMap.get(new BigInteger(childEnumOid));                        }else {                            childEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(childEnum);                        }                        // 在子枚举中查找匹配项                        List<EnumerationItemHandleVO> matchedChildItems = childEnumItems.stream()                                .filter(item -> value.equals(item.getDisplayName()))                                .collect(Collectors.toList());                        // 如果在子枚举中找到匹配项，使用内部名称                        if (CollUtil.isNotEmpty(matchedChildItems)) {                            continue;                        }                        if(parentEnumOid == null){                            List<EnumerationDefDO> parentEnumDefs = typlmEnumerationService.queryEnumDefByNames(                                    Collections.singletonList(classInfoDTO.getAttributeInName()));                            if(CollUtil.isNotEmpty(parentEnumDefs)){                                parentEnumOid = parentEnumDefs.get(0).getOid().toString();                            }                        }                        if(parentEnumOid != null){                            IdentifierEntity parentEnum = new IdentifierEntity();                            parentEnum.setOid(new BigInteger(parentEnumOid));                            parentEnum.setOtype(TableTypeConstrant.CTYOBJECTIDENTIFIER);                            List<EnumerationItemHandleVO> parentEnumItems;                            if(allParentEnumItemMap.containsKey(new BigInteger(parentEnumOid))){                                parentEnumItems = allParentEnumItemMap.get(new BigInteger(parentEnumOid));                            }else {                                parentEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(parentEnum);                            }                            // 在父枚举中查找匹配项                            List<EnumerationItemHandleVO> matchedParentItems = parentEnumItems.stream()                                    .filter(item -> value.equals(item.getDisplayName()))                                    .collect(Collectors.toList());                            if (CollUtil.isNotEmpty(matchedParentItems)) {                                // 合并父枚举和子枚举项                                List<EnumerationItemHandleVO> combinedItems = new ArrayList<>(childEnumItems);                                combinedItems.addAll(matchedParentItems);                                // 更新子枚举                                updateEnumItem(combinedItems, new BigInteger(parentEnumOid), new BigInteger(classInfoDTO.getAttributeMapOid()), childEnumOid, false);                            }else {                                List<EnumerationItemHandleVO> combinedItems = new ArrayList<>(childEnumItems);                                EnumerationItemHandleVO newItem = new EnumerationItemHandleVO();                                newItem.setDisplayName(value);                                newItem.setDisplayNameCn(value);                                newItem.setName(value);                                newItem.setState("true");                                newItem.setInternalName(value);                                combinedItems.add(newItem);                                updateEnumItem(combinedItems, new BigInteger(parentEnumOid), new BigInteger(classInfoDTO.getAttributeMapOid()), childEnumOid, false);                            }                        }                    }                }            }        }    }    @Override    public void importPatternCode(MultipartFile file) {        List<ImportPatternCodeDTO> dataList = new ArrayList<>();        try {            dataList = EasyExcel.read(file.getInputStream(), ImportPatternCodeDTO.class,                                      null)                    .sheet()                    .doReadSync();        } catch (Exception e) {            log.error("Excel文件读取失败", e);        }        LifeCycleTemplateDO lifeCycleTemplateDO = typlmLifecycleTemplateService.queryLifecycleByName(                "润通通用生命周期模板");        lifeCycleTemplateOid = lifeCycleTemplateDO.getOid();        PdmLinkProductDO pdmLinkProductDO = getPdmLinkProductDO("6-物料库");        SubfolderDO subfolderDO = getSubfolderDO(pdmLinkProductDO, "图样代号");        List<PartAttrsVO> partAttrsVOList = new ArrayList<>();        List<SaveObjIBADTO> needUpdatePartList = new ArrayList<>();        List<String> cardNotPartNumberList = new ArrayList<>();        List<String> descriptionErrorList = new ArrayList<>();        List<String> existPart = new ArrayList<>();        Map<String, List<ClassInfoDTO>> classInfoDTOMap = new HashMap<>();        List<List<ImportPatternCodeDTO>> dataListList = CommonUtil.subObjectList(dataList, 999);        Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap = new HashMap<>();        Map<BigInteger, List<EnumerationItemHandleVO>> allParentEnumItemMap = new HashMap<>();        for (List<ImportPatternCodeDTO> importPatternCodeDTOS : dataListList) {            List<String> classificationList = importPatternCodeDTOS.stream().map(item -> item.getCodeType() + "_" + item.getCardName())                    .distinct().collect(Collectors.toList());            Set<BigInteger> classIds = typlmClassificationService.batchQueryClassificationByNameList(classificationList)                    .stream().map(ClassificationDO::getOid).collect(Collectors.toSet());            List<ClassInfoDTO> classInfoDTOList = rtTypeClassMapper.selectClassInfoByClassId(ListUtil.toList(classIds));            Map<String, List<ClassInfoDTO>> classInfoDTOS = classInfoDTOList.stream().collect(Collectors.groupingBy(ClassInfoDTO::getClassName, LinkedHashMap::new, Collectors.toList()));            if(CollUtil.isNotEmpty(classInfoDTOS)){                classInfoDTOMap.putAll(classInfoDTOS);            }            List<String> partNumberList = importPatternCodeDTOS.stream().map(ImportPatternCodeDTO::getCode).distinct().collect(                    Collectors.toList());            List<String> partNumberListExist = rtPartMapper.checkPartNumberIfExist(partNumberList);            if(CollUtil.isNotEmpty(partNumberListExist)){                existPart.addAll(partNumberListExist);            }            List<List<ClassInfoDTO>> classInfoListList = CommonUtil.subObjectList(classInfoDTOList, 999);            for (List<ClassInfoDTO> classInfoList : classInfoListList) {                Set<String> childEnumIdList = classInfoList.stream().map(ClassInfoDTO::getChildEnumOid).collect(Collectors.toSet());                List<EnumerationItemHandleVO> childEnumItemList = enumMapper.batchSelectEnumByEnumId(ListUtil.toList(childEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> childEnumItemMap = childEnumItemList.stream().collect(Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if(CollUtil.isNotEmpty(childEnumItemMap)){                    allChildEnumItemMap.putAll(childEnumItemMap);                }                Set<String> parentEnumIdList = classInfoList.stream().map(ClassInfoDTO::getParentEnumOid).collect(Collectors.toSet());                List<EnumerationItemHandleVO> parentEnumItemList = enumMapper.batchSelectEnumByEnumId(ListUtil.toList(parentEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> parentEnumItemMap = parentEnumItemList.stream().collect(Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if(CollUtil.isNotEmpty(parentEnumItemMap)){                    allParentEnumItemMap.putAll(parentEnumItemMap);                }            }        }        for (ImportPatternCodeDTO dto : dataList) {            if (!classInfoDTOMap.containsKey(dto.getCodeType() + "_" + dto.getCardName())) {                cardNotPartNumberList.add(dto.getCode());                continue;            }            List<String> ibaAttrValue = Arrays.asList(dto.getIbaAttrValue().split(";;;"));            List<String> ibaAttrName = Arrays.asList(dto.getIbaAttrName().split(";;;"));            if (!areAllListsEqualSizeStream(ibaAttrValue, ibaAttrName)) {                descriptionErrorList.add(dto.getCode());            } else {                List<ClassInfoDTO> classInfoDTOS = classInfoDTOMap.get(dto.getCodeType() + "_" + dto.getCardName());                Map<String, String> describeRuleDTOS = new HashMap<>();                for (int i = 0; i < ibaAttrValue.size(); i++) {                    describeRuleDTOS.put(ibaAttrName.get(i), ibaAttrValue.get(i));                }                if (existPart.contains(dto.getCode())) {                    //该编码的物料在系统中存在                    PartDO partDO = rtPartMapper.queryLatestPartByNumberAndView(dto.getCode(), "Design", "");                    if(partDO != null){                        SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();                        CTyEntityBaseDO cTyEntityBaseDO = new CTyEntityBaseDO(partDO.getOid(),TableTypeConstrant.TY_PART_OTYPE);                        saveObjIBADTO.setCTyEntityBaseDO(cTyEntityBaseDO);                        List<IbaDTO> ibaDTOList = new ArrayList<>();                        //查询属性卡片                        if (CollUtil.isNotEmpty(classInfoDTOS)) {                            LinkedHashMap<String, List<String>> attrNameMap = dealClassIba(classInfoDTOS, describeRuleDTOS, allChildEnumItemMap, allParentEnumItemMap);                            dealPatternCodeCommonAttribute(dto, attrNameMap);                            for (String key : attrNameMap.keySet()) {                                addIbaDto(attrNameMap.get(key).get(0), ibaDTOList, key);                            }                            saveObjIBADTO.setObjIbaList(ibaDTOList);                            needUpdatePartList.add(saveObjIBADTO);                        } else {                            cardNotPartNumberList.add(dto.getCode());                        }                    }                } else {                    //该编码的物料在系统中不存在，执行创建，封装批量创建物料需要的入参                    log.info("导入零部件编码: {}", dto.getCode());                    PartAttrsVO partAttrsVO = getPartAttrsVO(dto, describeRuleDTOS, pdmLinkProductDO, subfolderDO, classInfoDTOS,                                                             allChildEnumItemMap, allChildEnumItemMap);                    partAttrsVOList.add(partAttrsVO);                }            }        }        commonDealInsertPart(needUpdatePartList, partAttrsVOList);        log.info("总计{}个，更新失败:{}个", dataList.size(), cardNotPartNumberList.size());        log.info("更新的零部件:{}",needUpdatePartList.size());        log.info("创建的零部件:{}",partAttrsVOList.size());        log.info("卡片不存在:{}个，零部件编码为： {}", cardNotPartNumberList.size(), cardNotPartNumberList);        log.info("描述规则错误:{}个，零部件编码为： {}", descriptionErrorList.size(), descriptionErrorList);        //导入表现        //            importPartPresentation(file,1);    }    private PartAttrsVO getPartAttrsVO(ImportPatternCodeDTO patternCodeDTO, Map<String,String> describeRuleDTOS, PdmLinkProductDO pdmLinkProductDO, SubfolderDO subfolderDO            , List<ClassInfoDTO> classInfoDTOS,Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap,Map<BigInteger, List<EnumerationItemHandleVO>> allparentEnumItemMap){        //设置物料基本属性        PartAttrsVO partAttrsVO = new PartAttrsVO();        partAttrsVO.setPartNumber(patternCodeDTO.getCode());        partAttrsVO.setName(patternCodeDTO.getName());        partAttrsVO.setTypeInthid("PatternCode");        //设置生命周期模板、视图、IBA扩展属性        partAttrsVO.setLifecycletemplateOid(lifeCycleTemplateOid.toString());        partAttrsVO.setViewName("Design");        LinkedHashMap<String, List<String>> ibaMap = dealClassIba(classInfoDTOS, describeRuleDTOS,allChildEnumItemMap, allparentEnumItemMap);        dealPatternCodeCommonAttribute(patternCodeDTO, ibaMap);        ibaMap.put("CompleteDescription", Collections.singletonList(patternCodeDTO.getIbaAttrValue().replace(";;;", "_")));        ibaMap.put("Description", Collections.singletonList(patternCodeDTO.getIbaAttrValue().replace(";;;", "_")));        partAttrsVO.setIbaMap(ibaMap);         if ("0".equals(patternCodeDTO.getStatus())) {            partAttrsVO.setLifecyclestatekey("DISABLED");        } else{            partAttrsVO.setLifecyclestatekey("RELEASED");        }            //设置放置物料的产品库        partAttrsVO.setContainerOid(pdmLinkProductDO.getOid());        partAttrsVO.setContainerOtype(pdmLinkProductDO.getOtype());        partAttrsVO.setSubFolderOid(subfolderDO.getOid());        partAttrsVO.setClassficaionOid(new BigInteger(classInfoDTOS.get(0).getClassOid()));        return partAttrsVO;    }    private LinkedHashMap<String, List<String>> dealClassIba(List<ClassInfoDTO> classInfoDTOS,                                                             Map<String, String> describeRuleDTOS,                                                             Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap,                                                             Map<BigInteger, List<EnumerationItemHandleVO>> allparentEnumItemMap) {        LinkedHashMap<String, List<String>> ibaMap = new LinkedHashMap<>();        for (ClassInfoDTO classInfoDTO : classInfoDTOS) {            String attributeDisName = classInfoDTO.getAttributeDisName();            if(describeRuleDTOS.containsKey(attributeDisName)){                String value = describeRuleDTOS.get(attributeDisName);                if(StringUtils.isEmpty(value) || StringUtils.isBlank(value)){                    continue;                }                String childEnumOid = classInfoDTO.getChildEnumOid();                String parentEnumOid = classInfoDTO.getParentEnumOid();                IdentifierEntity childEnum = new IdentifierEntity();                childEnum.setOid(new BigInteger(childEnumOid));                childEnum.setOtype(TableTypeConstrant.CTYOBJECTIDENTIFIER);                List<EnumerationItemHandleVO> childEnumItems;                if(allChildEnumItemMap.containsKey(new BigInteger(childEnumOid))){                    childEnumItems = allChildEnumItemMap.get(new BigInteger(childEnumOid));                }else {                    childEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(childEnum);                }                // 在子枚举中查找匹配项                List<EnumerationItemHandleVO> matchedChildItems = childEnumItems.stream()                        .filter(item -> value.equals(item.getDisplayName()))                        .collect(Collectors.toList());                // 如果在子枚举中找到匹配项，使用内部名称                if (CollUtil.isNotEmpty(matchedChildItems)) {                    ibaMap.put(classInfoDTO.getAttributeInName(),Collections.singletonList(matchedChildItems.get(0).getInternalName()));                    continue;                }                log.info("未找到匹配的子枚举项，将使用描述作为值:{},{}",attributeDisName,value);//                if(parentEnumOid == null){//                    List<EnumerationDefDO> parentEnumDefs = typlmEnumerationService.queryEnumDefByNames(//                            Collections.singletonList(classInfoDTO.getAttributeInName()));//                    if(CollUtil.isNotEmpty(parentEnumDefs)){//                        parentEnumOid = parentEnumDefs.get(0).getOid().toString();//                    }//                }//                if(parentEnumOid != null){//                    IdentifierEntity parentEnum = new IdentifierEntity();//                    parentEnum.setOid(new BigInteger(parentEnumOid));//                    parentEnum.setOtype(TableTypeConstrant.CTYOBJECTIDENTIFIER);//                    List<EnumerationItemHandleVO> parentEnumItems;//                    if(allparentEnumItemMap.containsKey(new BigInteger(parentEnumOid))){//                        parentEnumItems = allparentEnumItemMap.get(new BigInteger(parentEnumOid));//                    }else {//                        parentEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(parentEnum);//                    }//                    // 在父枚举中查找匹配项//                    List<EnumerationItemHandleVO> matchedParentItems = parentEnumItems.stream()//                            .filter(item -> value.equals(item.getDisplayName()))//                            .collect(Collectors.toList());//                    if (CollUtil.isNotEmpty(matchedParentItems)) {//                        ibaMap.put(classInfoDTO.getAttributeInName(),Collections.singletonList(matchedParentItems.get(0).getInternalName()));//                        // 合并父枚举和子枚举项//                        List<EnumerationItemHandleVO> combinedItems = new ArrayList<>(childEnumItems);//                        combinedItems.add(matchedParentItems.get(0));//                        // 更新子枚举//                        tyEnumerationdefService.updateEnumItem(combinedItems, new BigInteger(parentEnumOid), new BigInteger(classInfoDTO.getAttributeMapOid()), childEnumOid, false);//                    }else {//                        ibaMap.put(classInfoDTO.getAttributeInName(),Collections.singletonList(value));//                        List<EnumerationItemHandleVO> combinedItems = new ArrayList<>(childEnumItems);//                        EnumerationItemHandleVO newItem = new EnumerationItemHandleVO();//                        newItem.setDisplayName(value);//                        newItem.setDisplayNameCn(value);//                        newItem.setName(value);//                        newItem.setState("true");//                        newItem.setInternalName(value);//                        combinedItems.add(newItem);//                        tyEnumerationdefService.updateEnumItem(combinedItems, new BigInteger(parentEnumOid), new BigInteger(classInfoDTO.getAttributeMapOid()), childEnumOid, false);//                    }//                }            }        }        return ibaMap;    }    public void updateEnumItem(List<EnumerationItemHandleVO> enumItemVOS, BigInteger parentEnumOid,                               BigInteger attrLinkId, String childEnumOid, boolean isParent) {        HandleEnumItemDTO handleEnumItemDTO = new HandleEnumItemDTO();        handleEnumItemDTO.setEnumItemList(enumItemVOS);        handleEnumItemDTO.setDefoid(new BigInteger(childEnumOid));        typlmEnumerationService.handleEnumItemList(handleEnumItemDTO);        //查询枚举是否存在        if (!isParent) {            log.info("enumItemVOS =====> : {}",enumItemVOS.size());            String description =enumItemVOS.stream().map(EnumerationItemHandleVO::getName).sorted().collect(Collectors.joining(""));            JSONObject enumLinkData = rtEnumMapper.select(String.valueOf(attrLinkId));            if(ObjectUtil.isNotEmpty(enumLinkData)){                rtEnumMapper.delete(String.valueOf(attrLinkId));            }            rtEnumMapper.insertEnumDescription(childEnumOid, description, String.valueOf(attrLinkId),                                               String.valueOf(parentEnumOid));        }    }    private static void dealPatternCodeCommonAttribute(ImportPatternCodeDTO patternCodeDTO, LinkedHashMap<String, List<String>> ibaMap) {        ibaMap.put("devCode", Collections.singletonList(patternCodeDTO.getDevelopmentOrder())); // 开发令        ibaMap.put("productType", Collections.singletonList(patternCodeDTO.getModelNumber())); //机型号        ibaMap.put("ReferenceDrawingNumber", Collections.singletonList(patternCodeDTO.getReferenceDrawingNumber())); // 被参考图号        ibaMap.put("OutputRequirements", Collections.singletonList(patternCodeDTO.getRuleType())); //输出要求        ibaMap.put("VariationType", Collections.singletonList(patternCodeDTO.getChangeType())); // 变化类型        ibaMap.put("ChangePoint", Collections.singletonList(patternCodeDTO.getChangePoint())); //变化点        ibaMap.put("BasicDerivation", Collections.singletonList(patternCodeDTO.getBaseOrDerived()));// 基础/衍生        ibaMap.put("REMARK", Collections.singletonList(patternCodeDTO.getRemark())); //备注        ibaMap.put("historyDescription", Collections.singletonList(patternCodeDTO.getHistoryDescription())); // 历史描述        ibaMap.put("DoHideModel", Collections.singletonList(patternCodeDTO.getIsModelHidden())); // 是否隐藏机型        ibaMap.put("threeDModelNumber", Collections.singletonList(patternCodeDTO.getSource3DDrawingNumber())); //源3D图号        ibaMap.put("Products", Collections.singletonList(patternCodeDTO.getProductCategory())); // 产品类        ibaMap.put("Combination", Collections.singletonList(patternCodeDTO.getCombination())); // 组合        ibaMap.put("HistoricalInformation", Collections.singletonList(patternCodeDTO.getHistoryInfo())); // 历史信息    }    @Resource    private TyplmEnumerationService typlmEnumerationService;    @Resource    private TyEnumerationdefService tyEnumerationdefService;    private LinkedHashMap<String, List<String>> getClassIbaAttr2(ClassificationDO classificationDO,                                                                 Map<String, String> describeRuleMap) {        if(CollUtil.isEmpty(describeRuleMap)){            return new LinkedHashMap<>();        }        List<TyAttributeDefMapVO> tyAttributeDefMapVOS = typlmTypeService.queryInheritAttrDef(                classificationDO.getOid(), classificationDO.getOtype());        LinkedHashMap<String, List<String>> ibaMap = new LinkedHashMap<>();        for (TyAttributeDefMapVO attributeDefMapVO : tyAttributeDefMapVOS) {            String displayName = attributeDefMapVO.getDisplayName();            // 检查是否在描述规则映射中存在该属性            if (!describeRuleMap.containsKey(displayName)) {                continue;            }            String value = describeRuleMap.get(displayName);            // 查询该属性的约束条件            TyplmConstraintQueryDTO constraintQueryDTO = new TyplmConstraintQueryDTO();            constraintQueryDTO.setAttributereferenceoid(attributeDefMapVO.getOid());            constraintQueryDTO.setAttributereferenceotype(attributeDefMapVO.getOtype());            List<TyplmConstraintEditVO> constraintEditVOS = this.typlmConstraintExtService.getEntityConstraint(                    Collections.singletonList(constraintQueryDTO));            // 如果没有约束条件，直接使用原始值            if (CollUtil.isEmpty(constraintEditVOS)) {                ibaMap.put(attributeDefMapVO.getName(), Collections.singletonList(value));                continue;            }            // 查找枚举离散集约束            List<TyplmConstraintEditVO> enumConstraints = constraintEditVOS.stream()                    .filter(constraint -> "EnumDiscreteSetConstraint".equals(constraint.getKey()))                    .collect(Collectors.toList());            // 如果没有枚举约束，直接使用原始值            if (CollUtil.isEmpty(enumConstraints)) {                ibaMap.put(attributeDefMapVO.getName(), Collections.singletonList(value));                continue;            }            // 处理枚举约束            TyplmConstraintEditVO constraintEditVO = enumConstraints.get(0);            handleEnumConstraint(attributeDefMapVO, constraintEditVO, value, ibaMap);        }        return ibaMap;    }    private void handleEnumConstraint(TyAttributeDefMapVO attributeDefMapVO,                                      TyplmConstraintEditVO constraintEditVO,                                      String value,                                      LinkedHashMap<String, List<String>> ibaMap) {        // 获取子枚举项 ty.zddw.kernel.CTyObjectIdentifier        IdentifierEntity enumItemIdentifier = new IdentifierEntity();        enumItemIdentifier.setOid(new BigInteger(constraintEditVO.getEnumoid()));        enumItemIdentifier.setOtype(TableTypeConstrant.CTYOBJECTIDENTIFIER);        List<EnumerationItemHandleVO> childEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(enumItemIdentifier);        // 在子枚举中查找匹配项        List<EnumerationItemHandleVO> matchedChildItems = childEnumItems.stream()                .filter(item -> value.equals(item.getDisplayName()))                .collect(Collectors.toList());        // 如果在子枚举中找到匹配项，使用内部名称        if (CollUtil.isNotEmpty(matchedChildItems)) {            ibaMap.put(attributeDefMapVO.getName(),                       Collections.singletonList(matchedChildItems.get(0).getInternalName()));            return;        }        // 如果在子枚举中未找到，尝试在父枚举中查找        List<EnumerationDefDO> parentEnumDefs = typlmEnumerationService.queryEnumDefByNames(                Collections.singletonList(attributeDefMapVO.getName()));        if (CollUtil.isEmpty(parentEnumDefs)) {            return;        }        EnumerationDefDO parentEnumDef = parentEnumDefs.get(0);        List<EnumerationItemHandleVO> parentEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(                parentEnumDef.getIdentifierRef());        // 在父枚举中查找匹配项        List<EnumerationItemHandleVO> matchedParentItems = parentEnumItems.stream()                .filter(item -> value.equals(item.getDisplayName()))                .collect(Collectors.toList());        // 如果在父枚举中找到匹配项，需要同步更新子枚举        if (CollUtil.isNotEmpty(matchedParentItems)) {            // 合并父枚举和子枚举项            List<EnumerationItemHandleVO> combinedItems = new ArrayList<>(matchedParentItems);            combinedItems.addAll(childEnumItems);            // 更新子枚举            tyEnumerationdefService.updateEnumItem(combinedItems,                                                   parentEnumDef.getOid(),                                                   attributeDefMapVO.getOid(),                                                   constraintEditVO.getEnumoid(),                                                   false);            ibaMap.put(attributeDefMapVO.getName(),                       Collections.singletonList(matchedParentItems.get(0).getInternalName()));        } else {            // 如果在父子枚举中都未找到，创建新的枚举项            createNewEnumItems(attributeDefMapVO, constraintEditVO, parentEnumDef,                               parentEnumItems, childEnumItems, value, ibaMap);        }    }    private void createNewEnumItems(TyAttributeDefMapVO attributeDefMapVO,                                    TyplmConstraintEditVO constraintEditVO,                                    EnumerationDefDO parentEnumDef,                                    List<EnumerationItemHandleVO> parentEnumItems,                                    List<EnumerationItemHandleVO> childEnumItems,                                    String value,                                    LinkedHashMap<String, List<String>> ibaMap) {        // 创建新的枚举项        EnumerationItemHandleVO newItem = new EnumerationItemHandleVO();        newItem.setDisplayName(value);        newItem.setDisplayNameCn(value);        newItem.setName(value);        newItem.setState("true");        newItem.setInternalName(value);        // 添加到父枚举和子枚举        parentEnumItems.add(newItem);        childEnumItems.add(newItem);        // 更新枚举项        tyEnumerationdefService.updateEnumItem(childEnumItems,                                               parentEnumDef.getOid(),                                               attributeDefMapVO.getOid(),                                               constraintEditVO.getEnumoid(),                                               false);        tyEnumerationdefService.updateEnumItem(parentEnumItems,                                               null,                                               attributeDefMapVO.getOid(),                                               String.valueOf(parentEnumDef.getOid()),                                               true);        ibaMap.put(attributeDefMapVO.getName(), Collections.singletonList(value));    }    /**     * 查询指定编码的物料在系统中是否已经存在     */    private boolean checkPartExistByNumber(String partNumber) {        List<String> objNumberList = new ArrayList<>();        objNumberList.add(partNumber);        List<ObjNumberErrorVO> objNumberErrorVOS = tyPlmWorkSpaceObjectService.judgeObjNumberIsExist(objNumberList,                                                                                                     "ty.inteplm.part.CTyPart");        if (objNumberErrorVOS != null && !objNumberErrorVOS.isEmpty()) {            ObjNumberErrorVO objNumberErrorVO = objNumberErrorVOS.get(0);            return objNumberErrorVO.isExist();        }        return false;    }    @SafeVarargs    public final boolean areAllListsEqualSizeStream(List<String>... lists) {        return Arrays.stream(lists).map(List::size).distinct().limit(2).count() == 1;    }    @Override    public void importDoc(MultipartFile file) {        String filename = file.getOriginalFilename();        if (filename == null || (!filename.endsWith(".xls") && !filename.endsWith(".xlsx"))) {            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("文件格式错误，仅支持 xls 或 xlsx");        }        List<HyperlinkDTO> hyperlinkList = new ArrayList<>();        try (InputStream inputStream = file.getInputStream()) {            ProcessDocumentConfig listener = new ProcessDocumentConfig();            EasyExcel.read(inputStream, ImportDocumentDTO.class, listener).sheet().doRead();            List<ImportDocumentDTO> dataList = listener.getDataList();            PdmLinkProductDO pdmLinkProductDO = getPdmLinkProductDO("91-文档库");            QuerySubFolderOutDTO subfolderWebVOS = this.typlmSubFolderLinkService.querySubFolderInfoByContainer(pdmLinkProductDO.getIdentifierRef());            List<SubfolderWebVO> subfolderWebVOList = subfolderWebVOS.getDataList();            Map<String, String> subfolderNameRelOid = subfolderWebVOList.stream()                    .collect(Collectors.toMap(                            SubfolderWebVO::getName,                            SubfolderWebVO::getOid,                            (existing, replacement) -> existing                    ));            Set<String> projectNumberList = dataList.stream().map(ImportDocumentDTO::getProjectOrder).collect(Collectors.toSet());            List<JSONObject> objectList = projectDevOrderMapper.batchQueryProductOidByProjectNumber(new ArrayList<>(projectNumberList));            Map<String, String> projectNumberMap = objectList.stream()                    .filter(obj -> obj.containsKey("PROJECTNUMBER") && obj.containsKey("OID"))                    .collect(Collectors.toMap(                            obj -> obj.getString("PROJECTNUMBER"),                            obj -> obj.getString("OID"),                            (existing, replacement) -> existing                    ));            List<JSONObject> data = rtTypeClassMapper.selectAllTypeOidAndDisName();            Map<String, String> typeNameAndId = data.stream().collect(Collectors.toMap(item -> item.getString("VALUE"), item -> item.getString("OID"), (existing, replacement) -> existing));            for (ImportDocumentDTO importDocDTO : dataList) {                String documentType = importDocDTO.getDocumentType();                String documentFormat = importDocDTO.getDocumentFormat();                if (StringUtils.isBlank(documentType)) {                    throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("文档类型不能为空");                }                if("3D数据".equals(documentType) && "prt".equals(documentFormat)){                    CadDrawingDataDTO dto = CadDrawingDataDTO.convertToCadDrawingDataDTO(importDocDTO);                    dealDrawing(dto,UG);                }else if("图纸".equals(documentType) && "dwg".equals(documentFormat)){//                    CadDrawingDataDTO dto = CadDrawingDataDTO.convertToCadDrawingDataDTO(importDocDTO);//                    dealDrawing(dto,DWG);                    dealDwgFile(importDocDTO, hyperlinkList, projectNumberMap, subfolderNameRelOid, pdmLinkProductDO);                }else {                    dealCommonFile(importDocDTO, hyperlinkList, projectNumberMap, subfolderNameRelOid, pdmLinkProductDO, typeNameAndId);                }            }            if(CollUtil.isNotEmpty(hyperlinkList)){                // 项目交付区创建文档超链接                typlmHyperlinkService.batchCreateHyperlink(hyperlinkList);            }        } catch (Exception e) {            e.printStackTrace();            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException(e.getMessage());        }    }    private void dealDwgFile(ImportDocumentDTO importDocDTO, List<HyperlinkDTO> hyperlinkList,                             Map<String, String> projectNumberMap, Map<String, String> subfolderNameRelOid,                             PdmLinkProductDO pdmLinkProductDO) {        Import2dDocForTsDTO paramDTO = new Import2dDocForTsDTO();        paramDTO.setPartType(TableTypeConstrant.TY_PART_OTYPE);        paramDTO.setDocType(importDocDTO.getDocumentType());        paramDTO.setDocName(importDocDTO.getDocumentName());        paramDTO.setFolderId(subfolderNameRelOid.get(importDocDTO.getDocumentType()));        paramDTO.setContainerOid(String.valueOf(pdmLinkProductDO.getOid()));        paramDTO.setContainerOType(pdmLinkProductDO.getOtype());        UserDO user = TyAccountContext.getUser();        paramDTO.setUserID(String.valueOf(user.getOid()));        paramDTO.setAnalysis(true);        paramDTO.setNotAnalysisCode(importDocDTO.getDocumentName().split(" ")[0]);        paramDTO.setNotAnalysisName(importDocDTO.getDocumentName());        paramDTO.setOpeflag("buildRule-All");        String filePath = importDocDTO.getFilePath();//        Map<String, MultipartFile> files = getFileFromFtp(Collections.singletonList(filePath), fileFtpIp, Integer.parseInt(fileFtpPort));        String localFilePath = "Z:\\" + filePath.trim();        File localFile = new File(localFilePath);        MultipartFile file = convertLocalFileToMultipart(localFile);        paramDTO.setFile(file);        Map<String, Object> map = this.typlmImportDwgService.importDWGFile(paramDTO);        JSONObject documentVO = (JSONObject)map.get("CADDoc");        String projectOrder = importDocDTO.getProjectOrder();        String phaseName = importDocDTO.getPhaseName();        if (projectNumberMap.containsKey(projectOrder)) {            BigInteger projectProductOid = new BigInteger(projectNumberMap.get(projectOrder));            List<SubfolderWebVO> subfolderWebVOS = this.typlmSubFolderLinkService.querySubFolderListByParent(                    projectProductOid, TableTypeConstrant.TY_CABINET_OTYPE);            List<SubfolderWebVO> filterSubfolderWebVOS = subfolderWebVOS.stream().filter(                    subfolderWebVO -> subfolderWebVO.getName().equals(phaseName)).collect(Collectors.toList());            if(CollUtil.isNotEmpty(filterSubfolderWebVOS)){                HyperlinkDTO hyperlinkDTO = new HyperlinkDTO();                hyperlinkDTO.setName(documentVO.getString("code")+","+documentVO.getString("name"));                hyperlinkDTO.setOid(new BigInteger(documentVO.getString("docId")));                hyperlinkDTO.setOtype(TableTypeConstrant.TY_DOC_OTYPE);                String subFolderOid = filterSubfolderWebVOS.get(0).getOid();                hyperlinkDTO.setCabinetoid(projectProductOid);//产品库ID                hyperlinkDTO.setSubfolderoid(new BigInteger(subFolderOid));//文件夹ID                hyperlinkList.add(hyperlinkDTO);            }        }    }    private void dealCommonFile(ImportDocumentDTO dto, List<HyperlinkDTO> hyperlinkList, Map<String, String> projectNumberMap,Map<String, String> subfolderNameRelOid ,PdmLinkProductDO pdmLinkProductDO, Map<String, String> typeNameAndId) {        if (ObjectUtils.isEmpty(dto)) {            return;        }        CreateDocInputDTO createDocInputDTO = builderCreateDocInputDTO(dto,subfolderNameRelOid, pdmLinkProductDO, typeNameAndId);        String filePath = dto.getFilePath();//        Map<String, MultipartFile> files = getFileFromFtp(Collections.singletonList(filePath), fileFtpIp, Integer.parseInt(fileFtpPort));        String localFilePath = "D:" + filePath.trim();        File localFile = new File(localFilePath);        MultipartFile file = convertLocalFileToMultipart(localFile);        FileGroupDTO fileGroupDto = new FileGroupDTO();        fileGroupDto.setFiles(Collections.singletonList(file));        String typeOid = createDocInputDTO.getType();        if (StringUtils.isNotBlank(typeOid)) {            this.typlmTypeService.checkTypeInstance(Collections.singletonList(new BigInteger(typeOid)));        }        Map<String, List<String>> ibaMap = new HashMap<>();        ibaMap.put("productLine", Collections.singletonList(dto.getProductLine()));        ibaMap.put("developmentOrder", Collections.singletonList(dto.getDevelopmentOrder()));        ibaMap.put("machineModel", Collections.singletonList(dto.getMachineModel()));        ibaMap.put("partNumber", Collections.singletonList(dto.getPartNumber()));        SaveDocDTO saveDocDto = new SaveDocDTO();        saveDocDto.setCreateDocInputDTO(createDocInputDTO);        saveDocDto.setIbaAttribute(ibaMap);        saveDocDto.setFileGroupDto(fileGroupDto);        DocumentVO documentVO = typlmDocumentService.insertDoc(saveDocDto);        log.info("文档创建成功：{}", documentVO);        String projectOrder = dto.getProjectOrder();        String phaseName = dto.getPhaseName();        if (projectNumberMap.containsKey(projectOrder)) {            BigInteger projectProductOid = new BigInteger(projectNumberMap.get(projectOrder));//            List<SubfolderWebVO> subfolderWebVOS = this.typlmSubFolderLinkService.querySubFolderListByParent(//                    projectProductOid, TableTypeConstrant.TY_CABINET_OTYPE);            QuerySubFolderOutDTO querySubFolderOutDTO = this.typlmSubFolderLinkService.querySubFolderInfoListByContainer(                    new IdentifierEntity(projectProductOid, TableTypeConstrant.TY_PROJECT_TYPE));            Optional<SubfolderWebVO> optional = querySubFolderOutDTO.getDataList().stream().filter(                    subfolderWebVO -> subfolderWebVO.getName().equals(phaseName)).findFirst();            if(optional.isPresent()){                SubfolderWebVO subfolderWebVO = optional.get();                HyperlinkDTO hyperlinkDTO = new HyperlinkDTO();                hyperlinkDTO.setName(documentVO.getObjnumber()+","+documentVO.getName());                hyperlinkDTO.setOid(new BigInteger(documentVO.getOid().split(":")[1]));                hyperlinkDTO.setOtype(TableTypeConstrant.TY_DOC_OTYPE);                hyperlinkDTO.setContainerotype(TableTypeConstrant.TY_PROJECT_TYPE);                hyperlinkDTO.setCabinetoid(projectProductOid);//产品库ID                hyperlinkDTO.setSubfolderoid(new BigInteger(subfolderWebVO.getOid()));//文件夹ID                hyperlinkDTO.setFolderPath(subfolderWebVO.getFolderPath());                hyperlinkDTO.setCabinetoid(new BigInteger(subfolderWebVO.getCabinetoid()));                hyperlinkDTO.setCabinetotype(subfolderWebVO.getCabinetotype());                hyperlinkList.add(hyperlinkDTO);            }        }    }    private static MultipartFile convertToMultipartFile(String filePath) {        String[] split = org.apache.commons.lang3.StringUtils.split(filePath, "\\\\");        String fileName = split[split.length - 1];        try {            // 直接从URL获取本地文件路径（假设url已经是本地路径）            File localFile = new File(filePath);            // 验证文件存在性            if (!localFile.exists() || !localFile.isFile()) {                throw SystemErrorCodeEnum.FILE_NOT_EXIST.getException("本地文件不存在: " + filePath);            }            return new MockMultipartFile(fileName, fileName, "application/octet-stream",                                         Files.newInputStream(localFile.toPath()));        } catch (IOException e) {            log.error("文件读取异常", e);            throw RTErrorCodeEnum.CUSTOM_EXCEPTION.getException(fileName + "本地文件读取失败");        }    }    public Map<String,MultipartFile> getFileFromFtp(List<String> filePathList ,String ip, int port) {        Map<String,MultipartFile> multipartFileMap = new HashMap<>();        try {            ftpClient.connect(ip, port);            ftpClient.login(fileFtpUser, fileFtpPassword);            ftpClient.enterLocalActiveMode(); // 切换为主动模式            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);           // ftpClient.setControlEncoding(StandardCharsets.UTF_8.name());            int reply = ftpClient.getReplyCode();            if (!FTPReply.isPositiveCompletion(reply)) {                ftpClient.disconnect();                throw new IOException("FTP server refused connection.");            }            for (String filePath : filePathList) {                ByteArrayOutputStream output = new ByteArrayOutputStream();                try (InputStream inputStream = ftpClient.retrieveFileStream(filePath)) {                    if (inputStream == null) {                        throw new IOException("文件不存在或无法读取: " + filePath);                    }                    byte[] buffer = new byte[4096];                    int bytesRead;                    while ((bytesRead = inputStream.read(buffer)) != -1) {                        output.write(buffer, 0, bytesRead);                    }                    // 确保 retrieveFileStream 正确结束                    boolean success = ftpClient.completePendingCommand();                    if (!success) {                        throw new IOException("FTP 命令执行失败");                    }                }                byte[] fileBytes = output.toByteArray();                Path path = Paths.get(filePath);                String filename = path.getFileName().toString();                MockMultipartFile mockMultipartFile = new MockMultipartFile(filename, filename, "application/octet-stream", fileBytes);                multipartFileMap.put(filePath, mockMultipartFile);            }            return multipartFileMap;        } catch (IOException e) {            log.error("文件读取异常", e);            throw RTErrorCodeEnum.CUSTOM_EXCEPTION.getException(e.getMessage());        } finally {            try {                if (ftpClient.isConnected()) {                    ftpClient.logout();                    ftpClient.disconnect();                }            } catch (IOException e) {                log.warn("FTP 断开连接失败", e);            }        }    }    private CreateDocInputDTO builderCreateDocInputDTO(ImportDocumentDTO vo,Map<String, String> subfolderNameRelOid ,PdmLinkProductDO pdmLinkProductDO, Map<String, String> typeNameAndId) {        CreateDocInputDTO createDocInputDTO = new CreateDocInputDTO();        String documentType = vo.getDocumentType().trim();        if(!subfolderNameRelOid.containsKey(documentType)){            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("文件夹:"+documentType+"不存在");        }        if (StringUtils.isBlank(documentType)) {            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("文档类型不能为空");        }        if(!typeNameAndId.containsKey(documentType)){            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("类型在系统中不存在");        }        String typeOid = typeNameAndId.get(documentType);        createDocInputDTO.setNumber(StringUtils.trim(vo.getHistoryDocCode()));        createDocInputDTO.setName(StringUtils.trim(vo.getDocumentName()));        createDocInputDTO.setDocType(documentType);        createDocInputDTO.setType(typeOid);        createDocInputDTO.setCreator(vo.getCreator());        createDocInputDTO.setFolderId(subfolderNameRelOid.get(documentType));        createDocInputDTO.setContainerId(String.valueOf(pdmLinkProductDO.getOid()));        createDocInputDTO.setContainerType(TableTypeConstrant.TY_PDMLINKPRODUCT_OTYPE);        createDocInputDTO.setProductInfoID(String.valueOf(pdmLinkProductDO.getOid()));        return createDocInputDTO;    }    @Override    public List<PdmPartInfoVO> importStandardPart(MultipartFile file) {        try {            List<ImportStandardPartDTO> dataList = EasyExcel.read(file.getInputStream(), ImportStandardPartDTO.class,                                                                  null)                    .sheet()                    .doReadSync();            LifeCycleTemplateDO lifeCycleTemplateDO = typlmLifecycleTemplateService.queryLifecycleByName(                    "基本生命周期");            lifeCycleTemplateOid = lifeCycleTemplateDO.getOid();            PdmLinkProductDO pdmLinkProductDO = getPdmLinkProductDO("6-物料库");            SubfolderDO subfolderDO = getSubfolderDO(pdmLinkProductDO, "标准件");            List<SaveObjIBADTO> needUpdatePartList = new ArrayList<>();            List<PartAttrsVO> partAttrsVOList = new ArrayList<>();            for (ImportStandardPartDTO dto : dataList) {                if (checkPartExistByNumber(dto.getMaterialCode())) {                    log.info("该编码的物料在系统中存在:{}", dto.getMaterialCode());                    //该编码的物料在系统中存在                    PartDO partDO = rtPartMapper.queryLatestPartByNumberAndView(dto.getMaterialCode(), "Design", null);                    SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();                    CTyEntityBaseDO cTyEntityBaseDO = new CTyEntityBaseDO(partDO.getOid(), TableTypeConstrant.TY_PART_OTYPE);                    saveObjIBADTO.setCTyEntityBaseDO(cTyEntityBaseDO);                    List<IbaDTO> ibaDTOList = new ArrayList<>();                    addIbaDto(dto.getOldMaterialDescription(), ibaDTOList,"OldDescription");                    addIbaDto(dto.getHistoryInfo(), ibaDTOList,"HistoricalInformation");                    addIbaDto(dto.getCodeDescription(), ibaDTOList,"Description");                    addIbaDto(dto.getRemark(), ibaDTOList,"REMARK");                    addIbaDto(dto.getPartCode(), ibaDTOList,"ComponentCode");                    addIbaDto(dto.getSpecification(), ibaDTOList,"specification");                    addIbaDto(dto.getPitch(), ibaDTOList,"screwPitch");                    addIbaDto(dto.getPerformanceLevel(), ibaDTOList,"performance");                    addIbaDto(dto.getSurfaceTreatment(), ibaDTOList,"surfaceTreatment");                    addIbaDto(dto.getHarmfulSubstances(), ibaDTOList,"hazardousSubstance");                    addIbaDto(dto.getSpecialRequirements(), ibaDTOList,"specialRequirement");                    saveObjIBADTO.setObjIbaList(ibaDTOList);                    needUpdatePartList.add(saveObjIBADTO);                } else {                    PartAttrsVO partAttrsVO = getStandardPartAttrsVO(dto, pdmLinkProductDO, subfolderDO);                    partAttrsVOList.add(partAttrsVO);                }            }            commonDealInsertPart(needUpdatePartList,partAttrsVOList);            return null;        } catch (Exception e) {            throw new RuntimeException(e);        }    }    private @NotNull PartAttrsVO getStandardPartAttrsVO(ImportStandardPartDTO patternCodeDTO, PdmLinkProductDO pdmLinkProductDO, SubfolderDO subfolderDO) throws Exception {        //设置物料基本属性        PartAttrsVO partAttrsVO = new PartAttrsVO();        partAttrsVO.setPartNumber(patternCodeDTO.getMaterialCode());        partAttrsVO.setName(patternCodeDTO.getMaterialName());        partAttrsVO.setTypeInthid("Standard");        List<ClassificationDO> classificationDOS = typlmClassificationService.queryClassificationByName(                "B_" + patternCodeDTO.getPartCode());        partAttrsVO.setClassficaionOid(classificationDOS.get(0).getOid());        //设置生命周期模板、视图、IBA扩展属性        partAttrsVO.setLifecycletemplateOid(lifeCycleTemplateOid.toString());        partAttrsVO.setViewName("Design");        LinkedHashMap<String, List<String>> ibaMap = new LinkedHashMap<>();        ibaMap.put("oldMaterialCode", Collections.singletonList(patternCodeDTO.getOldMaterialCode()));        ibaMap.put("OldDescription", Collections.singletonList(patternCodeDTO.getOldMaterialDescription()));        ibaMap.put("HistoricalInformation", Collections.singletonList(patternCodeDTO.getHistoryInfo()));        ibaMap.put("Description", Collections.singletonList(patternCodeDTO.getCodeDescription()));        ibaMap.put("REMARK", Collections.singletonList(patternCodeDTO.getRemark()));        ibaMap.put("ComponentCode", Collections.singletonList(patternCodeDTO.getPartCode()));        ibaMap.put("specification", Collections.singletonList(patternCodeDTO.getSpecification()));        ibaMap.put("screwPitch", Collections.singletonList(patternCodeDTO.getPitch()));        ibaMap.put("performance", Collections.singletonList(patternCodeDTO.getPerformanceLevel()));        ibaMap.put("surfaceTreatment", Collections.singletonList(patternCodeDTO.getSurfaceTreatment()));        ibaMap.put("hazardousSubstance", Collections.singletonList(patternCodeDTO.getHarmfulSubstances()));        ibaMap.put("specialRequirement", Collections.singletonList(patternCodeDTO.getSpecialRequirements()));        partAttrsVO.setIbaMap(ibaMap);        partAttrsVO.setLifecyclestatekey("RELEASED");        //设置放置物料的产品库        partAttrsVO.setContainerOid(pdmLinkProductDO.getOid());        partAttrsVO.setContainerOtype(pdmLinkProductDO.getOtype());        partAttrsVO.setSubFolderOid(subfolderDO.getOid());        return partAttrsVO;    }    @Override    public List<PdmPartInfoVO> import3DDigitalModel(MultipartFile file) {        try {            List<CadDrawingDataDTO> dataList = EasyExcel.read(file.getInputStream(), CadDrawingDataDTO.class, null)                    .sheet().doReadSync();            for (CadDrawingDataDTO dto : dataList) {                if (!checkPartExistByNumber(dto.getCode()) && StringUtils.isNotBlank(dto.getFilePath())) {                    dealDrawing(dto,UG);                }            }        } catch (IOException e) {            throw new RuntimeException(e);        }        return Collections.emptyList();    }    private void dealDrawing(CadDrawingDataDTO dto,String type) {        Product product = getProduct(productName);        String workSpaceId = dataTransAdapter.getWorkSpaceId(product, drawFolder);        //构造标准化xml主体        Document standardXml = DocumentHelper.createDocument();        Element root = standardXml.addElement("root");        Element globe = root.addElement("globe");        globe.addAttribute("view", DESIGN);        globe.addAttribute("drwtype", "");        globe.addAttribute("BatchInputType", "Checkin");        globe.addAttribute("opeflag", "cadOnly");        Element workSpace = root.addElement("WorkSpace");        workSpace.addAttribute("WorkSpacePath", "");        workSpace.addAttribute("NetWorkSpaceId", workSpaceId);        Element docList = root.addElement("Doclist");        Element docStruct = root.addElement("DocStruct");        Map<String, MultipartFile> docNameRelMultipartFile = new HashMap<>();        long start = System.currentTimeMillis();        Map<String, Map<String, List<String>>> partRelDocMap = new HashMap<>();        initialCadDocList(docList, dto, product, docNameRelMultipartFile, partRelDocMap,type);        log.info("initialCadDocList 方法耗时：{}", (System.currentTimeMillis() - start) + "ms");        start = System.currentTimeMillis();        initialDocStruct(docStruct, dto, partRelDocMap);        log.info("initialDocStruct 方法耗时：{}", (System.currentTimeMillis() - start) + "ms");        start = System.currentTimeMillis();        if (UG.equals(type)) {            Map<String, Object> data = dataTransAdapter.importCadDocAndPart(standardXml);            log.info("importCadDocAndPart 方法耗时：{}", (System.currentTimeMillis() - start) + "ms");            if (ObjectUtils.isEmpty(data)) {                return;            }            List<CADContentDataVO> cadFileList = JSON.parseArray(JSONObject.toJSONString(data.get("CADFile")),                                                                 CADContentDataVO.class);            List<MDAImportOutDocVo> cadDocList = JSON.parseArray(JSONObject.toJSONString(data.get("CADDoc")),                                                                 MDAImportOutDocVo.class);            Map<String, String> cadOidRelFileName = new HashMap<>();            if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(cadFileList)) {                //获取附件和CAD文档关系                for (CADContentDataVO cadContentDataVO : cadFileList) {                    cadOidRelFileName.put(cadContentDataVO.getRelaObjectOID(), cadContentDataVO.getTFilePath());                }            }            //        挂接关系            start = System.currentTimeMillis();            generateDescAndPartLink(dto, new HashMap<>());            log.info("generateDescAndPartLink 方法耗时：{}", (System.currentTimeMillis() - start) + "ms");            log.info("上传文档附件到S3");            //上传文档附件到S3            Map<String, String> fileOidMap = new HashMap<>();            dataTransAdapter.uploadCadFile(cadDocList, docNameRelMultipartFile, cadOidRelFileName, fileOidMap);        }else if(DWG.equals( type)){            generateDescAndPartLink(dto,new HashMap<>());        }    }    private void generateDescAndPartLink(CadDrawingDataDTO cadDataDTO, HashMap<String, Integer> map) {        String key = cadDataDTO.getDrawingNumber();        Integer value = map.get(key);        if (value != null) {            return;        }        PartDO partDO = rtPartMapper.queryLatestPartByNumberAndView(cadDataDTO.getDrawingNumber(), DESIGN, null);        if (ObjectUtils.isNotEmpty(partDO)) {            BusinessObjectVO businessObjectVO = dataTransAdapter.checkOut(String.valueOf(partDO.getOid()),                                                                          TableTypeConstrant.TY_PART_OTYPE);            List<DocDetails> docDetails = typlmPartRelObjectService.queryPartRelatedDocInfo(businessObjectVO.getId());            List<BigInteger> cadOidList = new ArrayList<>();            String drawCode = cadDataDTO.getCode();            CADDocDO cadDocDO = dataTransAdapter.getLastCadDocByNumber(drawCode);            List<BigInteger> collect = docDetails.stream().filter(item -> drawCode.equals(item.getObjectNumber())).map(                    DocDetails::getLinkId).collect(Collectors.toList());            if (CollUtil.isNotEmpty(collect)) {                typlmCADDescribeLinkMapper.deleteCadDescribeLinkByIDS(collect);            }            cadOidList.add(cadDocDO.getOid());            if (CollUtil.isNotEmpty(cadOidList)) {                PartLinkCadDTO partLinkCadDTO = new PartLinkCadDTO();                partLinkCadDTO.setPartId(businessObjectVO.getId());                partLinkCadDTO.setCadIdList(cadOidList);                typlmPdmPartRelObjectService.batchCreateDescLink(partLinkCadDTO);            }            dataTransAdapter.checkIn(String.valueOf(businessObjectVO.getId()), TableTypeConstrant.TY_PART_OTYPE);        }    }    //    private void dealLifecycleStateAndOther(List<CADContentDataVO> cadFileList, List<MDAImportOutDocVo> cadDocList, Map<BigInteger, BigInteger> sourceOidAndNewOidMap, List<LifecycleVO> lifecycleVOList) {    //        if (CollUtil.isNotEmpty(sourceOidAndNewOidMap) && CollUtil.isNotEmpty(cadFileList) && CollUtil.isNotEmpty(cadDocList)) {    //            for (CADContentDataVO cadContentDataVO : cadFileList) {    //                BigInteger relaObjectOID = new BigInteger(cadContentDataVO.getRelaObjectOID());    //                if (sourceOidAndNewOidMap.containsKey(relaObjectOID)) {    //                    BigInteger oid = sourceOidAndNewOidMap.get(relaObjectOID);    //                    cadContentDataVO.setRelaObjectOID(oid.toString());    //                }    //            }    //            for (MDAImportOutDocVo mdaImportOutDocVo : cadDocList) {    //                BigInteger docOid = new BigInteger(mdaImportOutDocVo.getDocId());    //                if (sourceOidAndNewOidMap.containsKey(docOid)) {    //                    BigInteger oid = sourceOidAndNewOidMap.get(docOid);    //                    mdaImportOutDocVo.setDocId(oid.toString());    //                    mdaImportOutDocVo.setLastDocid(oid.toString());    //                    CADDocDO lastedEntityById = typlmCADDocMapper.getLastedEntityById(oid);    //                    mdaImportOutDocVo.setBranchid(lastedEntityById.getBranchid());    //                }    //            }    //        }    //        if (CollUtil.isNotEmpty(lifecycleVOList)) {    //            Lists.partition(lifecycleVOList, 100).forEach(    //                    list -> tyCommonLifecycleService.batchUpdateObjectLifecycleStatus(list)    //            );    //        }    //    }    private Product getProduct(String proName) {        // 判断是否已经有对应的产品库        JSONObject queryConditions = new JSONObject();        queryConditions.put("name", proName);        List<Product> productList = productService.getProductPage(queryConditions, TyAccountContext.getUser(), 1, 20)                .getList();        if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(productList)) {            return productList.get(0);        } else {            //默认产品库模板            Product product = new Product();            product.setContainerTemplate("产品库容器模板");            product.setContainerTemplateId("-20202020");            //所有者id            product.setOwnerOid(TyAccountContext.getUser().getOid().toString());            //是否私有权限-默认私有            product.setPrivateAccessContainerInfo("0");            Product insert = productService.insert(product);            SubfolderVO subfolder = new SubfolderVO();            subfolder.setParentOid(insert.getDefaultCabinetOid());            subfolder.setParentOtype(insert.getDefaultCabinetOtype());            subfolder.setName(drawFolder);            subfolder.setOtype(TableTypeConstrant.TY_SUBFOLDER_OTYPE);            typlmSubFolderLinkService.createSubfolder(subfolder);            return insert;        }    }    private void initialCadDocList(Element docList, CadDrawingDataDTO cadDataDTO, Product product,                                   Map<String, MultipartFile> docNameRelMultipartFile,                                   Map<String, Map<String, List<String>>> resultMap,String type) {        String folderId = dataTransAdapter.getSubfolder(product.getDefaultCabinetOid(),                                                        product.getDefaultCabinetOtype(), drawFolder).getOid();        String workSpaceId = dataTransAdapter.getWorkSpaceId(product, drawFolder);        Map<String, List<String>> idRelDim = new HashMap<>();        ArrayList<String> idList = new ArrayList<>();        idList.add(String.valueOf(ID));        idRelDim.put(THREE, idList);        String url = cadDataDTO.getFilePath();        String[] split = org.apache.commons.lang3.StringUtils.split(url, "/");        String fileName = split[split.length - 1];        String localFilePath = "Z:\\" + url.trim();        File localFile = new File(localFilePath);        MultipartFile file = convertLocalFileToMultipart(localFile);        log.info("从本地加载的文件 {}", localFilePath);        if (ObjectUtil.isNotEmpty(file)) {            docNameRelMultipartFile.put(fileName, file);        }else {            return;        }        if (UG.equals(type)) {            boolean isNew = true;            if (dataTransAdapter.verifyCadDocName(fileName)) {                //检出CAD文档                dataTransAdapter.checkOutCadDocByName(fileName, product, workSpaceId);                isNew = false;            }            // 构建XML文档节点            Element mainDocEl = docList.addElement("doc");            // 添加文档节点的属性            String dlgStatus = "New";            String opType = "upload";            if (Boolean.FALSE.equals(isNew)) {                dlgStatus = "CheckOut0";                opType = "checkin";            }            mainDocEl.addAttribute("DLGStatus", dlgStatus);            mainDocEl.addAttribute("optype", opType);            // id            mainDocEl.addAttribute("id", String.valueOf(ID));            mainDocEl.addAttribute("ogorder", String.valueOf(ID));            // subfolder 文件夹id            mainDocEl.addAttribute("subfolder", folderId);            // doctype            mainDocEl.addAttribute("doctype", "UG");            mainDocEl.addAttribute("parttype", TableTypeConstrant.TY_PART_OTYPE);            // DWG文件无鬼影文件，值为0            mainDocEl.addAttribute("PlaceHolder", "0");            // DWG文件无族表，值为0            mainDocEl.addAttribute("FamilyTableStatus", "0");            // 文件名  本地文件绝对路径            mainDocEl.addAttribute("filename", localFilePath);            // 暂未启用，固定值为"1"            mainDocEl.addAttribute("BoxExtentIsNull", "1");            mainDocEl.addAttribute("system", "UG");            // APPVersion置空，否则底座接口查不到数据抛异常            mainDocEl.addAttribute("AppVersion", "");            mainDocEl.addAttribute("relevance", "0");            // cadname            mainDocEl.addAttribute("DLGname", fileName);            // 默认给DLGGUID            mainDocEl.addAttribute("DLGGUID", cadDataDTO.getCode());            mainDocEl.addAttribute("Remark", fileName.substring(fileName.lastIndexOf(".")));            mainDocEl.addAttribute("createpart", "0");            String type2 = fileName.substring(fileName.lastIndexOf(".") + 1);            mainDocEl.addAttribute("type", type2.toUpperCase());            mainDocEl.addAttribute("DLGpath", product.getName() + "/默认产品库");            //添加attributes            Element attributes = mainDocEl.addElement("attributes");            Element attribute = attributes.addElement("attribute");            attribute.addAttribute("attributeKey", "code");            attribute.addAttribute("attributeValue", cadDataDTO.getCode());            resultMap.put(cadDataDTO.getDrawingNumber(), idRelDim);        }else if(DWG.equals(type)){            dealDwg(cadDataDTO, product, docNameRelMultipartFile, workSpaceId, folderId);        }    }    private void dealDwg(CadDrawingDataDTO cadDataDTO, Product product, Map<String, MultipartFile> docNameRelMultipartFile, String workSpaceId, String folderId) {        MultipartFile multipartFile = docNameRelMultipartFile.get(cadDataDTO.getFilePath());        Example example = new Example(CADDocMasterDO.class);        Example.Criteria criteria = example.createCriteria();        criteria.andEqualTo("docnumber", cadDataDTO.getCode());        List<CADDocMasterDO> cadDocMasterList = tyCadDocMasterMapper.selectByExample(example);        if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(cadDocMasterList)) {            CADDocMasterDO cadDocMasterDO = cadDocMasterList.get(0);            List<CADDocDO> cadDocDOList = tyCadDocumentService.queryLatestCadDocByMasterOIDs(Collections.singletonList(cadDocMasterDO.getOid()), TyAccountContext.getUser().getOid().toString());            if (org.apache.commons.lang3.ObjectUtils.isNotEmpty(cadDocDOList)) {                CADDocDO cadDocDO = tyCadDocumentService.checkoutCadDoc(cadDocDOList.get(0), TyAccountContext.getUser().getOid(), workSpaceId);                List<FileDataVO> fileListByEntity = fileHandleService.getFileListByEntity(new IdentifierEntity(cadDocDO.getOid(), cadDocDO.getOtype()));                if (CollUtil.isNotEmpty(fileListByEntity)) {                    List<BigInteger> collect = fileListByEntity.stream().map(item -> new BigInteger(item.getFileID())).collect(Collectors.toList());                    fileHandleService.deleteFileByFileIdList(collect);                }                //挂接文件                BatchUploadDTO batchUploadDTO = new BatchUploadDTO();                batchUploadDTO.setOid(cadDocDO.getOid().toString());                batchUploadDTO.setOtype(cadDocDO.getOtype());                batchUploadDTO.setFileList(ListUtil.toList(multipartFile));                List<ContentUploadDTO> contentUploadDTOS = fileHandleService.batchUploadFile(batchUploadDTO);                //检入                CADDocDO checkInCadDoc = tyCadDocumentService.checkInCadDoc(cadDocDO, TyAccountContext.getUser().getOid(), new BigInteger(workSpaceId));                buildLightweightAgainList(contentUploadDTOS, checkInCadDoc.getOid().toString());            }        } else {            InsertCadDocDTO insertCadDocDTO = new InsertCadDocDTO();            insertCadDocDTO.setAuthoringApplication("AutoCAD_CAD");            insertCadDocDTO.setNumber(cadDataDTO.getCode());            insertCadDocDTO.setName(cadDataDTO.getName());            insertCadDocDTO.setContainerId(product.getOid());            BigInteger typeOid = typlmTypeService.getLastTypeByName("AutoCAD").getOid();            insertCadDocDTO.setType(typeOid.toString());            insertCadDocDTO.setTypeDefName("AutoCAD");            insertCadDocDTO.setFolderId(folderId);            insertCadDocDTO.setCreator(TyAccountContext.getUser().getFullname());            insertCadDocDTO.setContainerType(TableTypeConstrant.TY_PDMLINKPRODUCT_OTYPE);            String oid = tyCadDocumentService.createCadDocByTemplate(insertCadDocDTO);            BatchUploadDTO batchUploadDTO = new BatchUploadDTO();            batchUploadDTO.setOid(oid);            batchUploadDTO.setOtype(TableTypeConstrant.TY_CADDOC_OTYPE);            batchUploadDTO.setFileList(ListUtil.toList(multipartFile));            List<ContentUploadDTO> contentUploadDTOS = fileHandleService.batchUploadFile(batchUploadDTO);            buildLightweightAgainList(contentUploadDTOS, oid);        }        docNameRelMultipartFile.remove(cadDataDTO.getFilePath());    }    private void buildLightweightAgainList(List<ContentUploadDTO> contentUploadDTOS, String oid) {        List<LightWeightAgainDTO> lightWeightAgainDTOList = new ArrayList<>();        if (CollUtil.isNotEmpty(contentUploadDTOS)) {            ContentUploadDTO contentUploadDTO = contentUploadDTOS.get(0);            LightWeightAgainDTO lightWeightAgainDTO = new LightWeightAgainDTO();            lightWeightAgainDTO.setFileId(new BigInteger(contentUploadDTO.getContentId()));            lightWeightAgainDTO.setLightWeightClass("1");            lightWeightAgainDTO.setObjId(oid);            lightWeightAgainDTO.setObjType(TableTypeConstrant.TY_CADDOC_OTYPE);            lightWeightAgainDTOList.add(lightWeightAgainDTO);        }        Map<String, Object> requestContext = RequestContext.currentContext();        CompletableFuture.runAsync(() -> {            RequestContext.attachContext(requestContext);            againLightWeight(lightWeightAgainDTOList);        });    }    private void againLightWeight(List<LightWeightAgainDTO> lightWeightAgainDTOList) {        if (CollUtil.isNotEmpty(lightWeightAgainDTOList)) {            for (LightWeightAgainDTO lightWeightAgainDTO : lightWeightAgainDTOList) {                typlmLightweightAgainService.performLightweightAgain(lightWeightAgainDTO);            }        }    }    /**     * 创建xml中文档之间的关系     *     * @param docStruct:     * @param cadDataDTO:     * @param docNumRelIdMap:     */    private void initialDocStruct(Element docStruct, CadDrawingDataDTO cadDataDTO,                                  Map<String, Map<String, List<String>>> docNumRelIdMap) {        String drawingNumber = cadDataDTO.getDrawingNumber();        //获取xml二维、三维文档id        Map<String, List<String>> docMap = docNumRelIdMap.get(drawingNumber);        if (docMap == null || docMap.isEmpty() || !docMap.containsKey(THREE)) {            return;        }        String ID = docMap.get(THREE).get(0);        //建立xml中文档三维与三维关系        Element struct = docStruct.addElement("Struct");        struct.addAttribute("number", "1");        struct.addAttribute("parentid", ID);        struct.addAttribute("identifier", String.valueOf(IDENTIFIER));        struct.addAttribute("childorder", String.valueOf(IDENTIFIER));        setStructRel(struct);    }    /**     * 设置xml中关系固定属性     *     * @param Struct:     */    private void setStructRel(Element Struct) {        Struct.addAttribute("DepType", "2");        Struct.addAttribute("isPlaced", "0");        Struct.addAttribute("visible", "1");        Struct.addAttribute("bomref", "1");        Struct.addAttribute("name", "");        Struct.addAttribute("isRequired", "1");        Struct.addAttribute("isSystem", "1");        Struct.addAttribute("locationnumber", "1");        Struct.addAttribute("isSuppressed", "0");        Struct.addAttribute("isflexible", "");        Struct.addAttribute("docref", "1");        Struct.addAttribute("Transform", "");    }    @Override    public void importPartPresentation(MultipartFile file, int sheetIndex) {        Map<String, MultipartFile> fileMap = parseDataByExcel(file,sheetIndex);        if (CollUtil.isNotEmpty(fileMap)) {            List<String> partNumberList = new ArrayList<>(fileMap.keySet());            List<List<String>> lists = CommonUtil.subObjectList(partNumberList, 999);            List<PartDO> partDOS = new ArrayList<>();            for (List<String> list : lists) {                List<PartDO> part = rtPartMapper.queryLatestPartByNumberList(list, null);                partDOS.addAll(part);            }            for (PartDO partDO : partDOS) {                List<DerivedImageVO> presentationList = this.typlmDerivedImageService.getPresentationList(                        partDO.getOid());                String partNumber = partDO.getPartnumber();                MultipartFile multipartFile = fileMap.get(partNumber);                if (CollUtil.isEmpty(presentationList)) {                    DerivedImageDTO derivedImageDTO = new DerivedImageDTO();                    derivedImageDTO.setObjId(partDO.getOid());                    derivedImageDTO.setObjType(TableTypeConstrant.TY_PART_OTYPE);                    derivedImageDTO.setMultipartFiles(Collections.singletonList(multipartFile));                    derivedImageDTO.setIsDefault(true);                    derivedImageDTO.setIsThumbnail(true);                    derivedImageDTO.setName(multipartFile.getOriginalFilename());                    typlmDerivedImageService.insertDerivedImageDO(derivedImageDTO);                } else {                    DerivedImageVO derivedImageVO = presentationList.get(0);                    this.typlmDerivedImageService.replaceThumbnail(derivedImageVO.getOid(), derivedImageVO.getOtype(),                                                                   multipartFile);                }            }        }    }    private Map<String, MultipartFile> parseDataByExcel(MultipartFile multipartFile, int sheetIndex) {        Map<String, MultipartFile> resultFileMap = new HashMap<>(); // 预设初始容量        if (multipartFile == null || multipartFile.isEmpty()) {            System.err.println("传入的Excel文件为空，无法解析");            return resultFileMap;        }        // 1. 读取Excel，获取物料编码与文件路径的映射关系        Map<String, String> partNumberPathMap = readPartNumberPathMap(multipartFile, sheetIndex);        if (partNumberPathMap.isEmpty()) {            System.out.println("Excel中未读取到有效数据，返回空结果");            return resultFileMap;        }        // 2. 遍历映射关系，将本地文件转换为MultipartFile        for (Map.Entry<String, String> entry : partNumberPathMap.entrySet()) {            String partNumber = entry.getKey();            String fileRelativePath = entry.getValue();            if (fileRelativePath == null || fileRelativePath.trim().isEmpty()) {                log.info("物料编码[{}]对应的文件路径为空，跳过处理" ,partNumber);                continue;            }            // 构建完整本地路径            String localFilePath = "Z:\\" + fileRelativePath.trim();            File localFile = new File(localFilePath);            // 转换文件并放入结果集            MultipartFile multipartFileObj = convertLocalFileToMultipart(localFile);            if (multipartFileObj != null) {                resultFileMap.put(partNumber, multipartFileObj);                log.info("物料编码[{}]对应的文件转换成功：{}", partNumber, localFilePath);            } else {                log.info("物料编码[{}]对应的文件转换失败：{}", partNumber, localFilePath);            }        }        return resultFileMap;    }    /**     * 将本地文件转换为MultipartFile对象     * @param localFile 本地文件     * @return 转换后的MultipartFile，失败返回null     */    private MultipartFile convertLocalFileToMultipart(File localFile) {        // 校验文件有效性        if (localFile == null || !localFile.exists() || !localFile.isFile()) {            System.err.println("文件无效（不存在或为目录）：" + (localFile != null ? localFile.getAbsolutePath() : "null"));            return null;        }        // 使用try-with-resources自动关闭文件流        try (FileInputStream fis = new FileInputStream(localFile)) {            String fileName = localFile.getName();            String contentType = getContentType(fileName);            // 创建MockMultipartFile（参数依次：表单字段名、原始文件名、内容类型、文件流）            return new MockMultipartFile(                    "file",    // 表单字段名，可根据实际接口调整                    fileName,                    contentType,                    fis            );        } catch (Exception e) {            log.error("文件转换失败：{}" , e.getMessage());            e.printStackTrace();        }        return null;    }    /**     * 从Excel中读取物料编码与文件路径的映射关系     */    private Map<String, String> readPartNumberPathMap(MultipartFile excelFile, int sheetIndex) {        Map<String, String> map = new HashMap<>(16);        try (InputStream inputStream = excelFile.getInputStream()) { // 自动关闭输入流            ExcelReader excelReader = ExcelUtil.getReader(inputStream, sheetIndex);            excelReader.setIgnoreEmptyRow(true);            int rowCount = excelReader.getRowCount();            int startRow = 1; // 起始行（跳过表头）            for (int rowNum = startRow; rowNum < rowCount; rowNum++) {                String materialCode = getExlCellValue(excelReader, 0, rowNum); // 物料编码（第0列）                String fileUrl = getExlCellValue(excelReader, 1, rowNum);      // 文件路径（第1列）                if (materialCode != null && !materialCode.trim().isEmpty()) {                    map.put(materialCode.trim(), fileUrl); // 去空格，避免key重复                } else {                    log.info("第{}行数据无效，请检查Excel文件", rowNum );                }            }        } catch (Exception e) {            log.error("读取Excel失败：{},==>{}", e, e.getMessage());            e.printStackTrace();        }        return map;    }    private static String getContentType(String fileName) {        if (fileName == null || fileName.isEmpty()) {            return null;        }        String extension = fileName.substring(fileName.lastIndexOf(".") + 1).toLowerCase();        switch (extension) {            case "txt": return "text/plain";            case "pdf": return "application/pdf";            case "doc": return "application/msword";            case "docx": return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";            case "xls": return "application/vnd.ms-excel";            case "xlsx": return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";            case "jpg": case "jpeg": return "image/jpeg";            case "png": return "image/png";            default: return null; // 未知类型        }    }    @Override    public List<PdmPartInfoVO> importSpecialPart(MultipartFile file) {        try {            List<ImportSpecialPartDTO> dataList = EasyExcel.read(file.getInputStream(), ImportSpecialPartDTO.class,                                                                 null)                    .sheet()                    .doReadSync();            LifeCycleTemplateDO lifeCycleTemplateDO = typlmLifecycleTemplateService.queryLifecycleByName(                    "基本生命周期");            lifeCycleTemplateOid = lifeCycleTemplateDO.getOid();            PdmLinkProductDO pdmLinkProductDO = getPdmLinkProductDO("6-物料库");            SubfolderDO subfolderDO = getSubfolderDO(pdmLinkProductDO, "物料码");            List<PartAttrsVO> partAttrsVOList = new ArrayList<>();            List<SaveObjIBADTO> needUpdatePartList = new ArrayList<>();            List<String> existPart = new ArrayList<>();            Map<String, List<ClassInfoDTO>> classInfoDTOMap = new HashMap<>();            Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap = new HashMap<>();            Map<BigInteger, List<EnumerationItemHandleVO>> allParentEnumItemMap = new HashMap<>();            List<List<ImportSpecialPartDTO>> dataListList = CommonUtil.subObjectList(dataList, 999);            for (List<ImportSpecialPartDTO> data : dataListList) {                List<String> classificationList = data.stream().map(item -> item.getDrawingCodeCardType() + "_" + item.getDrawingCodeCardName())                        .distinct().collect(Collectors.toList());                Set<BigInteger> classIds = typlmClassificationService.batchQueryClassificationByNameList(classificationList)                        .stream().map(ClassificationDO::getOid).collect(Collectors.toSet());                List<ClassInfoDTO> classInfoDTOList = rtTypeClassMapper.selectClassInfoByClassIdContainsParentAttribute(ListUtil.toList(classIds));                Map<String, List<ClassInfoDTO>>  map = classInfoDTOList.stream().collect(Collectors.groupingBy(ClassInfoDTO::getClassName, LinkedHashMap::new, Collectors.toList()));                if(CollUtil.isNotEmpty(map)){                    classInfoDTOMap.putAll(map);                }                List<String> partNumberList = data.stream().map(ImportSpecialPartDTO::getCode).distinct().collect(                        Collectors.toList());                List<String> partNumberListExist = rtPartMapper.checkPartNumberIfExist(partNumberList);                if(CollUtil.isNotEmpty(partNumberListExist)){                    existPart.addAll(partNumberListExist);                }                List<List<ClassInfoDTO>> classInfoListList = CommonUtil.subObjectList(classInfoDTOList, 999);                for (List<ClassInfoDTO> classInfoList : classInfoListList) {                    Set<String> childEnumIdList = classInfoList.stream().map(ClassInfoDTO::getChildEnumOid).collect(Collectors.toSet());                    List<EnumerationItemHandleVO> childEnumItemList = enumMapper.batchSelectEnumByEnumId(ListUtil.toList(childEnumIdList));                    Map<BigInteger, List<EnumerationItemHandleVO>> childEnumItemMap = childEnumItemList.stream().collect(Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                    if(CollUtil.isNotEmpty(childEnumItemMap)){                        allChildEnumItemMap.putAll(childEnumItemMap);                    }                    Set<String> parentEnumIdList = classInfoList.stream().map(ClassInfoDTO::getParentEnumOid).collect(Collectors.toSet());                    List<EnumerationItemHandleVO> parentEnumItemList = enumMapper.batchSelectEnumByEnumId(ListUtil.toList(parentEnumIdList));                    Map<BigInteger, List<EnumerationItemHandleVO>> parentEnumItemMap = parentEnumItemList.stream().collect(Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                    if(CollUtil.isNotEmpty(parentEnumItemMap)){                        allParentEnumItemMap.putAll(parentEnumItemMap);                    }                }            }//            Set<String> allDrawingCodeNumber = dataList.stream().map(ImportSpecialPartDTO::getDrawingNumber).collect(//                    Collectors.toSet());//            List<List<String>> numberList = CommonUtil.subObjectList(ListUtil.toList(allDrawingCodeNumber), 999);//            Map<String, List<AttributeVO>> allAttrMaps = new HashMap<>();//            for (List<String> numbers : numberList) {//                List<PartDO> partDOS = rtPartMapper.batchQueryLatestMaterialByViewAndView(numbers, null, null);//                if(CollUtil.isNotEmpty(partDOS)){//                    List<BigInteger> partNumberOid = partDOS.stream().map(PartDO::getOid).collect(Collectors.toList());//                    Map<String, List<AttributeVO>> attrMaps = typlmAttributeValueService.getAttrValueTableByEntitys(//                            partNumberOid, TableTypeConstrant.TY_PART_OTYPE);//                    if(CollUtil.isNotEmpty(attrMaps)){//                        allAttrMaps.putAll(attrMaps);//                    }//                }//            }////            Map<String, Map<String, List<String>>> transformedMap = allAttrMaps.entrySet().stream()//                    .collect(Collectors.toMap(//                            Map.Entry::getKey,//                            entry -> entry.getValue().stream()//                                    .collect(Collectors.groupingBy(//                                            AttributeVO::getAttributeName,//                                            Collectors.mapping(//                                                    AttributeVO::getAttributeValue,//                                                    Collectors.toList()//                                            )//                                    ))//                    ));            for (ImportSpecialPartDTO dto : dataList) {                Map<String, String>  describeRuleMap = getDescribeRuleDTOList(dto.getDescriptionRuleItem(),                                                                                   dto.getDescriptionRuleValue());                if(classInfoDTOMap.containsKey(dto.getDrawingCodeCardType() + "_" + dto.getDrawingCodeCardName())){                    List<ClassInfoDTO> classInfoDTOS = classInfoDTOMap.get(dto.getDrawingCodeCardType() + "_" + dto.getDrawingCodeCardName());                    if (existPart.contains(dto.getCode())) {                        //更新                        PartDO partDO = rtPartMapper.queryLatestPartByNumberAndView(dto.getCode(), "Design", null);                        SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();                        CTyEntityBaseDO cTyEntityBaseDO = new CTyEntityBaseDO(partDO.getOid(), TableTypeConstrant.TY_PART_OTYPE);                        saveObjIBADTO.setCTyEntityBaseDO(cTyEntityBaseDO);                        List<IbaDTO> ibaDTOList = new ArrayList<>();                        LinkedHashMap<String, List<String>>  attrNameMap = dealClassIba(classInfoDTOS, describeRuleMap, allChildEnumItemMap, allParentEnumItemMap);                        dealSpecialPartCommonIbaAttr(dto, attrNameMap);                        for (String key : attrNameMap.keySet()) {                            addIbaDto(attrNameMap.get(key).get(0), ibaDTOList,key);                        }                        saveObjIBADTO.setObjIbaList(ibaDTOList);                        needUpdatePartList.add(saveObjIBADTO);                    } else {                        //该编码的物料在系统中不存在，执行创建，封装批量创建物料需要的入参                        PartAttrsVO partAttrsVO = getPartAttrsVO(dto, describeRuleMap, pdmLinkProductDO, subfolderDO, classInfoDTOS, allChildEnumItemMap, allParentEnumItemMap);                        partAttrsVOList.add(partAttrsVO);                    }                } else {                    log.error("未找到对应的分类：{}", dto.getCardType() + "_" + dto.getCardName());                }            }            commonDealInsertPart(needUpdatePartList, partAttrsVOList);            return null;        } catch (IOException e) {            throw new RuntimeException(e);        }    }    private void commonDealInsertPart(List<SaveObjIBADTO> needUpdatePartList, List<PartAttrsVO> partAttrsVOList) {        if(CollUtil.isNotEmpty(needUpdatePartList)){            //更新属性            List<List<SaveObjIBADTO>> lists = CommonUtil.subObjectList(needUpdatePartList, 800);            for (List<SaveObjIBADTO> list : lists) {                typlmAttributeValueService.batchSaveIBAByObjsNoConstraint(list, false);            }        }        if(CollUtil.isNotEmpty(partAttrsVOList)){            List<List<PartAttrsVO>> partAttrsVOListList = CommonUtil.subObjectList(partAttrsVOList, 800);            for (List<PartAttrsVO> list : partAttrsVOListList) {                typlmPdmPartService.batchAddPart(list);            }        }    }    private PdmLinkProductDO getPdmLinkProductDO(String productName) {        List<PdmLinkProductDO> pdmLinkProductDOS = BatchQueryHelper.queryExampleColumnIn(ListUtil.toList(productName),                                                                                         PdmLinkProductDO.class,                                                                                         "name",                                                                                         typlmPdmLinkProductMapper);        if(CollUtil.isEmpty(pdmLinkProductDOS)){            throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException(                    "创建物料失败，物料库在系统中不存在");        }        return pdmLinkProductDOS.get(0);    }    private SubfolderDO getSubfolderDO(PdmLinkProductDO pdmLinkProductDO,String key) {        Example exampleSubfolder = new Example(SubfolderDO.class, true, true);        Example.Criteria criteriaSubfolder = exampleSubfolder.createCriteria();        criteriaSubfolder.andEqualTo("name",key).andEqualTo("containeroid",                                                               pdmLinkProductDO.getOid()).andEqualTo("containerotype",                                                                                                     pdmLinkProductDO.getOtype());        List<SubfolderDO> subfolderDOS = typlmSubfolderMapper.selectByExample(exampleSubfolder);        if(CollUtil.isEmpty(subfolderDOS)){            throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException(                    "创建物料失败，专用件文件夹在系统中不存在");        }        return subfolderDOS.get(0);    }    private static void addIbaDto(String value, List<IbaDTO> ibaDTOList,String key) {        IbaDTO ibaDTO = new IbaDTO();        ibaDTO.setKey(key);        ibaDTO.setValue(value);        ibaDTOList.add(ibaDTO);    }    private PartAttrsVO getPartAttrsVO(ImportSpecialPartDTO dto, Map<String,String> describeRuleMap,                                       PdmLinkProductDO pdmLinkProductDO, SubfolderDO subfolderDO, List<ClassInfoDTO> classInfoDTOS,    Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap,                                       Map<BigInteger, List<EnumerationItemHandleVO>> allparentEnumItemMap) {        PartAttrsVO partAttrsVO = new PartAttrsVO();        partAttrsVO.setPartNumber(dto.getCode());        partAttrsVO.setName(dto.getName());        partAttrsVO.setTypeInthid("MaterialCode");        //设置生命周期模板、视图、IBA扩展属性        partAttrsVO.setLifecycletemplateOid(lifeCycleTemplateOid.toString());        partAttrsVO.setViewName("Design");        partAttrsVO.setClassficaionOid(new BigInteger(classInfoDTOS.get(0).getClassOid()));        LinkedHashMap<String, List<String>> ibaMap = dealClassIba(classInfoDTOS, describeRuleMap, allChildEnumItemMap, allparentEnumItemMap);        dealSpecialPartCommonIbaAttr(dto, ibaMap);        partAttrsVO.setIbaMap(ibaMap);        if ("0".equals(dto.getStatus())) {            partAttrsVO.setLifecyclestatekey("DISABLED");        } else {            partAttrsVO.setLifecyclestatekey("RELEASED");        }        //设置放置物料的产品库        partAttrsVO.setContainerOid(pdmLinkProductDO.getOid());        partAttrsVO.setContainerOtype(pdmLinkProductDO.getOtype());        partAttrsVO.setSubFolderOid(subfolderDO.getOid());        return partAttrsVO;    }    private void dealSpecialPartCommonIbaAttr(ImportSpecialPartDTO dto, LinkedHashMap<String, List<String>> ibaMap) {        PartDO partDO = rtPartMapper.queryLatestPartByNumberAndView(dto.getDrawingNumber().trim(), "Design", null);        ibaMap.put("MaterialCodeDescription", Collections.singletonList(dto.getDescriptionRuleValue().replace(";;;", "_")));        ibaMap.put("Description", Collections.singletonList(dto.getDescriptionRuleValue().replace(";;;", "_")));        if (partDO != null) {            Map<String, List<String>> ibaAttribute = this.typlmAttributeService.getIbaAttributeMap(partDO.getOid(), partDO.getOtype());            ibaMap.putAll(ibaAttribute);            if (ibaAttribute.containsKey("CompleteDescription")) {                List<String> strings = ibaAttribute.get("CompleteDescription");                if (!strings.isEmpty()) {                    ibaMap.put("MaterialCodeDescription", Collections.singletonList(                            strings.get(0) + ";" + dto.getDescriptionRuleValue().replace(";;;", "_")));                    ibaMap.put("PatternCodeDescription", Collections.singletonList(strings.get(0)));                }            }            if (ibaAttribute.containsKey("Description")) {                List<String> strings = ibaAttribute.get("Description");                if (!strings.isEmpty()) {                    ibaMap.put("Description", Collections.singletonList(                            strings.get(0) + ";" + dto.getDescriptionRuleValue().replace(";;;", "_")));                    ibaMap.put("Common_Attributes|1757215074349", Collections.singletonList(strings.get(0)));                }            }        }        ibaMap.put("PatternCode", Collections.singletonList(dto.getDrawingNumber()));        ibaMap.put("HistoricalInformation", Collections.singletonList(dto.getHistoryInfo()));        ibaMap.put("oldMaterialCode", Collections.singletonList(dto.getOldMaterialCode()));        ibaMap.put("OldDescription", Collections.singletonList(dto.getOldMaterialDescription()));        ibaMap.put("REMARK", Collections.singletonList(dto.getRemark()));    }    @Override    public void importEbomHistoryData(MultipartFile file) {        try {            List<ImportEbomCodeDTO> dataList = EasyExcel.read(file.getInputStream(), ImportEbomCodeDTO.class, null)                    .sheet().doReadSync();            if (CollUtil.isEmpty(dataList)) {                return;            }            LifeCycleTemplateDO lifeCycleTemplateDO = typlmLifecycleTemplateService.queryLifecycleByName(                    "基本生命周期");            lifeCycleTemplateOid = lifeCycleTemplateDO.getOid();            PdmLinkProductDO pdmLinkProductDO = getPdmLinkProductDO("6-物料库");            SubfolderDO subfolderDO = getSubfolderDO(pdmLinkProductDO, "EBOM号");            List<PartAttrsVO> partAttrsVOList = new ArrayList<>();            List<SaveObjIBADTO> needUpdatePartList = new ArrayList<>();            List<String> error = new ArrayList<>();            for (ImportEbomCodeDTO dto : dataList) {                Map<String,String> describeRuleMap = getDescribeRuleDTOList(dto.getDescriptionRuleItem(),                                                                                   dto.getDescriptionRuleValue());                if (checkPartExistByNumber(dto.getCode())) {                    //更新                    PartDO partDO = rtPartMapper.queryLatestPartByNumberAndView(dto.getCode(), "Design", null);                    if (partDO != null) {                        SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();                        CTyEntityBaseDO cTyEntityBaseDO = new CTyEntityBaseDO(partDO.getOid(), TableTypeConstrant.TY_PART_OTYPE);                        saveObjIBADTO.setCTyEntityBaseDO(cTyEntityBaseDO);                        List<IbaDTO> ibaDTOList = new ArrayList<>();                        List<ClassificationDO> classificationDOS = typlmClassificationService.queryClassificationByName("L_" + dto.getCode().substring(0, 3));                        LinkedHashMap<String, List<String>>  attrNameMap = getClassIbaAttr2(classificationDOS.get(0),describeRuleMap);                        dealEbomCommonAttribute(dto, attrNameMap);                        for (String key : attrNameMap.keySet()) {                            addIbaDto(attrNameMap.get(key).get(0), ibaDTOList,key);                        }                        saveObjIBADTO.setObjIbaList(ibaDTOList);                        needUpdatePartList.add(saveObjIBADTO);                    } else {                        error.add(dto.getCode());                    }                } else {                    //该编码的物料在系统中不存在，执行创建，封装批量创建物料需要的入参                    PartAttrsVO partAttrsVO = getPartAttrsVO(dto, describeRuleMap, pdmLinkProductDO, subfolderDO);                    partAttrsVOList.add(partAttrsVO);                }            }            if (CollUtil.isNotEmpty(needUpdatePartList)) {                //更新属性                List<List<SaveObjIBADTO>> updateList = CommonUtil.subObjectList(needUpdatePartList, 800);                for (List<SaveObjIBADTO> saveObjIBADTOS : updateList) {                    typlmAttributeValueService.batchSaveIBAByObjsNoConstraint(saveObjIBADTOS, false);                }            }            List<List<PartAttrsVO>> partDetailLists = CommonUtil.subObjectList(partAttrsVOList, 800);            for (List<PartAttrsVO> partDetailList : partDetailLists) {                typlmPdmPartService.batchAddPart(partDetailList);            }            if(CollUtil.isNotEmpty(error)){                log.info("===========提示信息============> 找不到的编码为：{}", error);            }        } catch (IOException e) {            e.printStackTrace();            throw new RuntimeException(e);        }    }    private Map<String, String> getDescribeRuleDTOList(String descriptionRuleItem, String descriptionRuleValue) {        Map<String, String> describeRuleMap = new HashMap<>();        if (StringUtils.isEmpty(descriptionRuleItem) || StringUtils.isEmpty(descriptionRuleValue)) {            return Collections.emptyMap();        }        List<String> ibaAttrName = Arrays.asList(descriptionRuleItem.split(";;;"));        List<String> ibaAttrValue = Arrays.asList(descriptionRuleValue.split(";;;"));        if (!areAllListsEqualSizeStream(ibaAttrValue, ibaAttrName)) {            throw new IllegalArgumentException("iba 属性值数量不一致，请检查数据格式");        } else {            for (int i = 0; i < ibaAttrValue.size(); i++) {                describeRuleMap.put(ibaAttrName.get(i), ibaAttrValue.get(i));            }        }        return describeRuleMap;    }    private PartAttrsVO getPartAttrsVO(ImportEbomCodeDTO dto, Map<String,String> describeRuleDTOS, PdmLinkProductDO pdmLinkProductDO, SubfolderDO subfolderDO) {        PartAttrsVO partAttrsVO = new PartAttrsVO();        partAttrsVO.setPartNumber(dto.getCode());        partAttrsVO.setTypeInthid("EBOM_NUM");        partAttrsVO.setName(dto.getCode());        partAttrsVO.setViewName("Design");        List<ClassificationDO> classificationDOS = typlmClassificationService.queryClassificationByName("L_" + dto.getCode().substring(0, 3));        ClassificationDO classificationDO = classificationDOS.get(0);        partAttrsVO.setClassficaionOid(classificationDO.getOid());        LinkedHashMap<String, List<String>> ibaMap = getClassIbaAttr2(classificationDO, describeRuleDTOS);        // 类型属性        partAttrsVO.setIbaMap(ibaMap);        if ("生效".equals(dto.getStatus())) {            partAttrsVO.setLifecyclestatekey("RELEASED");        } else if ("失效".equals(dto.getStatus())) {            partAttrsVO.setLifecyclestatekey("DISABLED");        }        dealEbomCommonAttribute(dto, ibaMap);        //设置放置物料的产品库        partAttrsVO.setContainerOid(pdmLinkProductDO.getOid());        partAttrsVO.setContainerOtype(pdmLinkProductDO.getOtype());        partAttrsVO.setSubFolderOid(subfolderDO.getOid());        return partAttrsVO;    }    private static void dealEbomCommonAttribute(ImportEbomCodeDTO dto, LinkedHashMap<String, List<String>> ibaMap) {        ibaMap.put("HistoricalCoding", Collections.singletonList(dto.getHistoricalCode())); //历史编码        ibaMap.put("devCode", Collections.singletonList(dto.getDevelopmentOrder())); //开发令        ibaMap.put("ProductLine", Collections.singletonList(dto.getProductLine())); // 产品线        ibaMap.put("ProductType", Collections.singletonList(dto.getProductType())); // 产品类型        ibaMap.put("productType", Collections.singletonList(dto.getMachineModel())); // 机型号        ibaMap.put("HistoricalModels", Collections.singletonList(dto.getHistoricalMachineModel())); //历史机型号        ibaMap.put("CertificationRequire", Collections.singletonList(dto.getCertificationRequirement())); // 认证要求        ibaMap.put("NeedBatch", Collections.singletonList(dto.getNeedSmallBatch())); //需小批        ibaMap.put("BatchProcessed", Collections.singletonList(dto.getIsBatchProduction())); //是否已批量        ibaMap.put("RecommendLevel", Collections.singletonList(dto.getRecommendationLevel())); //推荐级别        ibaMap.put("ModelMachine", Collections.singletonList(dto.getIsPrototype())); //样机        ibaMap.put("MadeVietnam", Collections.singletonList(dto.getVietnamProduction())); //越南生产        ibaMap.put("TestRequire", Collections.singletonList(dto.getTestRequirement())); //测试要求        ibaMap.put("HalfBOM", Collections.singletonList(dto.getHalfBOM())); //半BOM        ibaMap.put("companyModel", Collections.singletonList(dto.getCompanyFilingModel())); //公司备案机型        ibaMap.put("historyDescription", Collections.singletonList(dto.getHistoricalDescription())); //历史描述        ibaMap.put("smallBatchQuantity", Collections.singletonList(dto.getSmallBatchQuantity())); //小批数量        ibaMap.put("developmentProject", Collections.singletonList(dto.getDevelopmentProject())); //开发项目        ibaMap.put("customerModel", Collections.singletonList(dto.getCustomerFilingModel())); //客户备案机型        ibaMap.put("BareMetalCodeStatus", Collections.singletonList(dto.getNakedMachineStatus())); //裸机码状态        ibaMap.put("FinishedProductCode", Collections.singletonList(dto.getFinishedProductCode())); //成品码        ibaMap.put("HistoricalInformation", Collections.singletonList(dto.getHistoricalInformation())); //历史信息//        ibaMap.put("description", Collections.singletonList(dto.getDescription())); //描述        ibaMap.put("Description", Collections.singletonList(dto.getDescription()));        ibaMap.put("CompleteDescription", Collections.singletonList(dto.getDescription()));        ibaMap.put("REMARK", Collections.singletonList(dto.getRemarks())); //备注    }    private ClassificationDO getClassificationDO(String type) {        List<ClassificationDO> classificationDOS = typlmClassificationService.queryClassificationByName(type);        if (CollUtil.isEmpty(classificationDOS)) {            throw RTErrorCodeEnum.DESCRIBE_RULE_ERROR.getException("创建物料失败，规则类型:" + type + "在系统中不存在");        }        return classificationDOS.get(0);    }    public static String getExlCellValue(ExcelReader excelReader, int x, int y) {        Cell cell = excelReader.getCell(x, y);        if (cell == null)            return "";        CellType cellType = cell.getCellType();        FormulaEvaluator evaluator = excelReader.getWorkbook().getCreationHelper().createFormulaEvaluator();        switch (cellType) {            case STRING:                return cell.getStringCellValue();            case NUMERIC:                if (DateUtil.isCellDateFormatted(cell)) {                    return cell.getLocalDateTimeCellValue().toString();                } else {                    BigDecimal value = new BigDecimal(cell.getNumericCellValue());//                    value = value.setScale(3, BigDecimal.ROUND_HALF_UP);                    return value.toPlainString();                }            case BOOLEAN:                return String.valueOf(cell.getBooleanCellValue());            case FORMULA:                // 评估公式并获取结果                switch (evaluator.evaluate(cell).getCellType()) {                    case STRING:                        return evaluator.evaluate(cell).getStringValue();                    case NUMERIC:                        return String.valueOf(evaluator.evaluate(cell).getNumberValue());                    case BOOLEAN:                        return String.valueOf(evaluator.evaluate(cell).getBooleanValue());                    default:                        return "";                }            default:                return "";        }    }    @Override    public void batchImportBom(MultipartFile file, HttpServletResponse response) {        try {            List<ImportBOMItemDTO> bomItemList = new ArrayList<>();            Set<String> notExistsPartNumber = new HashSet<>();            boolean flag = readExcelAndBuildTree(file, bomItemList,notExistsPartNumber);            if(false){                // 将上传的原始文件写入响应流，返回给浏览器下载                String fileName = file.getOriginalFilename();                String encodeFileName = null;                if (fileName != null) {                    encodeFileName = URLEncoder.encode(fileName, String.valueOf(StandardCharsets.UTF_8));                }                response.setContentType("application/vnd.ms-excel");                response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);                try (InputStream is = file.getInputStream()) {                    byte[] buffer = new byte[1024];                    int len;                    OutputStream os = response.getOutputStream();                    while ((len = is.read(buffer)) > 0) {                        os.write(buffer, 0, len);                    }                }                return;            }            if (CollUtil.isNotEmpty(bomItemList)) {                ViewDefDO view = typlmViewDefService.getViewByName(DESIGN);                List<SaveObjIBADTO> objWithIbaList = new ArrayList<>();                for (ImportBOMItemDTO importBOMItemDTO : bomItemList) {                    batchAddPartUsageLink(importBOMItemDTO,view,objWithIbaList);                }                typlmAttributeValueService.batchSaveIBAByObjList(objWithIbaList, false);            }            if(CollUtil.isNotEmpty(bomItemList)){                log.info("不存在的零件:{}", notExistsPartNumber);            }        } catch (IOException e) {            throw new RuntimeException(e);        }    }    private void batchAddPartUsageLink(ImportBOMItemDTO parentPart, ViewDefDO view,List<SaveObjIBADTO> objWithIbaList) {        typlmPartUsageLinkService.batchDeletePartUsageLink(rtPartMapper.batchQueryPartUsageLinkDOByPartOid(Collections.singletonList(parentPart.getOid())));        List<ImportBOMItemDTO> childLines = parentPart.getChildren();        if(CollUtil.isNotEmpty(childLines)){            PartBomView partBomView = new PartBomView();            PartBomTreeNode parent = new PartBomTreeNode();            parent.setOid(parentPart.getOid());            parent.setOtype(TableTypeConstrant.TY_PART_OTYPE);            parent.setViewID(view.getOid());            partBomView.setParent(parent);            List<PartBomTreeNode> bomTreeNodeList = IntStream.range(0, childLines.size())                    .mapToObj(i -> {                        ImportBOMItemDTO partChildBomDTO = childLines.get(i);                        String childNumber = partChildBomDTO.getCode();                        String quantity = partChildBomDTO.getCount();                        long quenceNo = (i + 1) * 10L;                        partChildBomDTO.setQuenceNo(quenceNo);                        PartBomTreeNode partBomTreeNode = new PartBomTreeNode();                        partBomTreeNode.setViewName(DESIGN);                        partBomTreeNode.setPartoid(String.valueOf(partChildBomDTO.getOid()));                        partBomTreeNode.setPartotype(TableTypeConstrant.TY_PART_OTYPE);                        try {                            double amountD = Double.parseDouble(quantity);                            partBomTreeNode.setAmount(amountD);                        } catch (Exception e) {                            partBomTreeNode.setAmount(1d);                        }                        partBomTreeNode.setMasterpartnumber(childNumber);                        partBomTreeNode.setParentPartNumber(parentPart.getCode());                        partBomTreeNode.setValue(quenceNo);                        partBomTreeNode.setAction("add");                        return partBomTreeNode;                    })                    .collect(Collectors.toList());            partBomView.setBomTreeNodeList(bomTreeNodeList);            Map<BigInteger, Long> map = typlmPartBomAdapter.saveBomViewImmediately(partBomView);            // 将 map 的 key 赋值到 usageLinkOid            Map<Long, BigInteger> reversedMap = map.entrySet().stream()                    .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));            for (ImportBOMItemDTO dto : childLines) {                Long quenceNo = dto.getQuenceNo();                if (quenceNo != null && reversedMap.containsKey(quenceNo)) {                    BigInteger usageLinkOid = reversedMap.get(quenceNo);                    dto.setUsageLinkOid(usageLinkOid);                }            }            buildSaveIbaDTO(parentPart, objWithIbaList);            for (ImportBOMItemDTO child : childLines) {                batchAddPartUsageLink(child, view,objWithIbaList);            }        }    }    public void buildSaveIbaDTO(ImportBOMItemDTO importPartBomDTO, List<SaveObjIBADTO> objWithIbaList) {        List<ImportBOMItemDTO> childLines = importPartBomDTO.getChildren();        for (ImportBOMItemDTO partChildBomDTO : childLines) {            List<IbaDTO> objIbaList = new ArrayList<>();            IbaDTO ibaDTO1 = new IbaDTO();            ibaDTO1.setKey("SegmNum");            ibaDTO1.setValue(partChildBomDTO.getSegment());            objIbaList.add(ibaDTO1);            IbaDTO ibaDTO2 = new IbaDTO();            ibaDTO2.setKey("ManufacturingAttr");            ibaDTO2.setValue(partChildBomDTO.getManufacturing());            objIbaList.add(ibaDTO2);            IbaDTO ibaDTO3 = new IbaDTO();            ibaDTO3.setKey("Position");            ibaDTO3.setValue(partChildBomDTO.getLocation());            objIbaList.add(ibaDTO3);            if (CollUtil.isNotEmpty(objIbaList)) {                SaveObjIBADTO saveObjIBADTO = new SaveObjIBADTO();                CTyEntityBaseDO ctyEntityBaseDO = new CTyEntityBaseDO();                ctyEntityBaseDO.setOid(partChildBomDTO.getUsageLinkOid());                ctyEntityBaseDO.setOtype(TableTypeConstrant.TY_PARTUSAGELINK_OTYPE);                saveObjIBADTO.setCTyEntityBaseDO(ctyEntityBaseDO);                saveObjIBADTO.setObjIbaList(objIbaList);                objWithIbaList.add(saveObjIBADTO);            }        }    }    private void batchDeletePartUsageLink(List<ImportBOMItemDTO> filterPartNumbers) {        log.info("batchDeletePartUsageLink--->批量移除结构---->{}", CollUtil.isNotEmpty(filterPartNumbers) ? JSON.toJSONString(filterPartNumbers) : null);        log.info("batchDeletePartUsageLink--->批量移除结构---->{}", CollUtil.isNotEmpty(filterPartNumbers) ? filterPartNumbers.size() : null);        List<BigInteger> oids = filterPartNumbers.stream()                .map(ImportBOMItemDTO::getOid)                .collect(Collectors.toList());        List<List<BigInteger>> lists = CommonUtil.subObjectList(oids, 300);        // 使用普通循环处理        for (List<BigInteger> list : lists) {            typlmPartUsageLinkService.batchDeletePartUsageLink(rtPartMapper.batchQueryPartUsageLinkDOByPartOid(list));        }    }    private boolean readExcelAndBuildTree(MultipartFile file, List<ImportBOMItemDTO> bomItemList, Set<String> notExistsPartNumber) throws IOException {        InputStream inputStream = null;        ExcelReader excelReader = null;        StringBuilder sb = new StringBuilder();        inputStream = file.getInputStream();        excelReader = ExcelUtil.getReader(inputStream, 0);        excelReader.setIgnoreEmptyRow(true);        int rowCount = excelReader.getRowCount();        //  读取Excel文件的起始行        int readExcelBeginRow = 1;        ExcelWriter excelWriter = ExcelUtil.getWriter(); // 创建 ExcelWriter        excelWriter.setSheet(0); // 设置操作的 sheet 页        List<ImportBOMItemDTO> items = new ArrayList<>();        int index = 1;        Map<String, ImportBOMItemDTO> itemMap = new HashMap<>(); // key: code, value: item        Map<Integer, ImportBOMItemDTO> parentMap = new HashMap<>();        boolean flag = false;        boolean remark = false;        // key: level, value: current parent        for (int i = readExcelBeginRow; i < rowCount; i++) {            String level = getExlCellValue(excelReader, 0, i);            if(remark){                if("1".equals(level)){                    continue;                } else if("0".equals(level)){                    remark = false;                }            }            index = index+1;            String code = getExlCellValue(excelReader, 1, i);            String name = getExlCellValue(excelReader, 2, i);            String count = getExlCellValue(excelReader, 3, i);            String segment = getExlCellValue(excelReader, 4, i);            String location = getExlCellValue(excelReader, 5, i);            String manufacturing = getExlCellValue(excelReader, 6, i);            ImportBOMItemDTO item = new ImportBOMItemDTO(index, level, code, name, count, segment, location, manufacturing, new ArrayList<>());            PartDO partDO = rtPartMapper.queryLatestPartByNumberAndView(code, DESIGN, "");            if(ObjectUtils.isEmpty(partDO)){                if("0".equals(level)){                    remark = true;                }                notExistsPartNumber.add(code);                excelWriter.writeCellValue(7, index, "未找到对应的部件");                flag = true;                continue;            }            item.setOid(partDO.getOid());            items.add(item);            itemMap.put(code, item);            // 处理父子关系            int currentLevel = Integer.parseInt(level);            ImportBOMItemDTO parent = null;            // 找到当前层级的父节点（上一层）            if (currentLevel > 0) {                parent = parentMap.get(currentLevel - 1);            }            if (parent != null) {                parent.getChildren().add(item);            } else {                // 根节点（level=0）                if (currentLevel == 0) {                    parentMap.put(0, item);                }            }            // 更新当前层级的父节点            parentMap.put(currentLevel, item);        }        List<ImportBOMItemDTO> bomTreeList = items.stream()                .filter(item -> item.getLevel().equals("0"))                .collect(Collectors.toList());        if(CollUtil.isNotEmpty(bomTreeList)){            bomItemList.addAll(bomTreeList);        }        return flag;    }    @Override    public void importProcessDoc(MultipartFile file) throws Exception{        List<ImportProcessFileDTO> dataList = EasyExcel.read(file.getInputStream(), ImportProcessFileDTO.class, null)                .sheet()                .doReadSync();        List<ImportProcessFileDTO> nonEmptyList = dataList.stream()                .filter(ImportProcessFileDTO::isRowEmpty) // 注意取反操作                .collect(Collectors.toList());        if(CollUtil.isEmpty( nonEmptyList)){            throw SystemErrorCodeEnum.EXCEL_READ_EXCEPTION.getException("Excel中未找到有效数据");        }        PdmLinkProductDO pdmLinkProductDO = getPdmLinkProductDO("91-文档库");        QuerySubFolderOutDTO subfolderWebVOS = this.typlmSubFolderLinkService.querySubFolderInfoByContainer(pdmLinkProductDO.getIdentifierRef());        List<SubfolderWebVO> subfolderWebVOList = subfolderWebVOS.getDataList();        Map<String, String> subfolderNameRelOid = subfolderWebVOList.stream()                .collect(Collectors.toMap(                        SubfolderWebVO::getName,                        SubfolderWebVO::getOid,                        (existing, replacement) -> existing                ));        for (ImportProcessFileDTO importProcessFileDTO : nonEmptyList) {            dealProcessFile(importProcessFileDTO,subfolderNameRelOid, pdmLinkProductDO);        }    }    private void dealProcessFile(ImportProcessFileDTO dto, Map<String, String> subfolderNameRelOid, PdmLinkProductDO pdmLinkProductDO) {        CreateDocInputDTO createDocInputDTO = builderCreateProcessDocInputDTO(dto,subfolderNameRelOid, pdmLinkProductDO);        String filePath = dto.getFilePath();        log.info("================>filePath:{}", filePath);        MultipartFile multipartFile = convertToMultipartFile(filePath);        List<MultipartFile> multipartFiles = new ArrayList<>();        multipartFiles.add(multipartFile);        FileGroupDTO fileGroupDto = new FileGroupDTO();        fileGroupDto.setFiles(multipartFiles);        String typeOid = createDocInputDTO.getType();        if (StringUtils.isNotBlank(typeOid)) {            this.typlmTypeService.checkTypeInstance(Collections.singletonList(new BigInteger(typeOid)));        }        Map<String, List<String>> ibaMap = new HashMap<>();        ibaMap.put("productLine", Collections.singletonList(dto.getModelSet()));        ibaMap.put("developmentOrder", Collections.singletonList(dto.getDevOrder()));        ibaMap.put("machineModel", Collections.singletonList(dto.getCustomer()));        ibaMap.put("partNumber", Collections.singletonList(dto.getFactory()));        ibaMap.put("partNumb2er", Collections.singletonList(dto.getLineBody()));        SaveDocDTO saveDocDto = new SaveDocDTO();        saveDocDto.setCreateDocInputDTO(createDocInputDTO);        saveDocDto.setIbaAttribute(ibaMap);        saveDocDto.setFileGroupDto(fileGroupDto);        typlmDocumentService.insertDoc(saveDocDto);    }    private CreateDocInputDTO builderCreateProcessDocInputDTO(ImportProcessFileDTO vo,Map<String, String> subfolderNameRelOid ,PdmLinkProductDO pdmLinkProductDO) {        CreateDocInputDTO createDocInputDTO = new CreateDocInputDTO();        String documentType = vo.getDocType().trim();        if(!subfolderNameRelOid.containsKey(documentType)){            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("文件夹:"+documentType+"不存在");        }        if (StringUtils.isBlank(documentType)) {            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("文档类型不能为空");        }        BigInteger typeOid = typlmTypeService.getTypeOidByName(documentType);        if (typeOid == null) {            throw RTErrorCodeEnum.DOC_TYPE_ERROR.getException("类型在系统中不存在");        }        createDocInputDTO.setNumber(StringUtils.trim(vo.getDocCode()));        createDocInputDTO.setName(StringUtils.trim(vo.getDocName()));        createDocInputDTO.setDocType(documentType);        createDocInputDTO.setType(typeOid.toString());        createDocInputDTO.setCreator(vo.getCustomer());        createDocInputDTO.setFolderId(subfolderNameRelOid.get(documentType));        createDocInputDTO.setContainerId(String.valueOf(pdmLinkProductDO.getOid()));        createDocInputDTO.setContainerType(TableTypeConstrant.TY_PDMLINKPRODUCT_OTYPE);        createDocInputDTO.setProductInfoID(String.valueOf(pdmLinkProductDO.getOid()));        return createDocInputDTO;    }    @Override    public void downloadTemplate(HttpServletResponse response, String fileName) {        String templateFileName = commonService.getFilePath("templates/"+fileName);        File sourceFile = new File(templateFileName);        // 修正文件名编码问题        String encodeFileName = null;        try {            encodeFileName = URLEncoder.encode(fileName, String.valueOf(StandardCharsets.UTF_8)).replace("+", "%20");        } catch (UnsupportedEncodingException e) {            log.error("编码转化失败: {}", e.getMessage());            e.printStackTrace();        }        // 设置响应头        response.setContentType("application/vnd.ms-excel");        response.setHeader("Content-Disposition", "attachment;filename=" + encodeFileName);        response.setCharacterEncoding("UTF-8");        // 将文件内容写入响应输出流        try (InputStream inputStream = Files.newInputStream(sourceFile.toPath());             OutputStream outputStream = response.getOutputStream()) {            byte[] buffer = new byte[1024];            int bytesRead;            while ((bytesRead = inputStream.read(buffer)) != -1) {                outputStream.write(buffer, 0, bytesRead);            }            outputStream.flush();        } catch (IOException e) {            log.error("文件下载失败: {}", e.getMessage());            e.printStackTrace();        }    }    @Resource    private RTClassificationService rtClassificationService;    @Resource    private TyplmClassificationRootService typlmClassificationRootService;    @Resource    private RTClassificationMapper rtClassificationMapper;    @Resource    private RTEnumMapper rtEnumMapper;    @Resource    private RTAttributeCardService rtAttributeCardService;    @Resource    private TyplmAttributeDefService typlmAttributeDefService;    @Override    public void importClassification(MultipartFile file) {        log.info("开始解析文档");        List<ImportCategoryAttributeCardDTO> categoryAttributeCardDTOS = rtClassificationService.getCategoryAttributeCardDTOS(file);        Map<String, CategoryAttributeCardDTO> map = CategoryAttributeCardDTO.convert(categoryAttributeCardDTOS);        log.info("categoryAttributeCardDTOList===> : {}", map.size());        //获取跟分类        List<TyplmClassificationEntityDTO> classRootDTOList = this.typlmClassificationRootService.queryClassificationRootByLanguage();        List<TyplmClassificationEntityDTO> classRoots = classRootDTOList.stream().filter(item -> ("零部件").equals(item.getDisplayName())).collect(Collectors.toList());        String classRootId = classRoots.get(0).getId();        List<TyplmClassificationEntityDTO> partChildClassDTOS = this.typlmClassificationService.queryClassificationByRoot(classRootId);        List<TyplmClassificationEntityDTO> cardParent = partChildClassDTOS.stream().filter(item -> ("编码").equals(item.getDisplayName())).collect(Collectors.toList());        String cardParentId = cardParent.get(0).getId();        List<TyplmClassificationEntityDTO> classificationEntityDTOS = this.typlmClassificationService.queryClassification(cardParentId);        //获取品类Map集合        Map<String, TyplmClassificationEntityDTO> categoryMap = classificationEntityDTOS.stream().collect(Collectors.toMap(                TyplmClassificationEntityDTO::getInternalName,                Function.identity(),                (oldValue, newValue) -> oldValue));        BigInteger ibaGroupId = rtClassificationMapper.selectIbaGroupId("SXKP");        BigInteger enumGroupId = rtEnumMapper.selectEnumGroupId("Attribute Card Enums");        List<TyplmConstraintRuleDefVO> enumDiscreteSetConstraintVOS = buildEnumConstraintInfo();        int i = 0;        List<CategoryAttributeCardDTO> createErrorList = new ArrayList<>();        List<CategoryAttributeCardDTO> hsaExictList = new ArrayList<>();        List<CategoryAttributeCardDTO> createSuccessList = new ArrayList<>();        List<CategoryAttributeCardDTO> notFindCategoryList = new ArrayList<>();        Set<String> errorCategoryName = new HashSet<>();        for (CategoryAttributeCardDTO dto : map.values()) {            log.info("处理分类第:{}个", i++);            log.info("处理分类内部名称:{}，显示名称: {}", dto.getCategoryInName(), dto.getCategoryDisName());            String categoryDisName = dto.getCategoryDisName();            if ("T".equals(dto.getCategoryType())) {                categoryDisName = "T_" + dto.getCategoryInName();            } else if ("W".equals(dto.getCategoryType())) {                categoryDisName = "W_" + dto.getCategoryInName();            } else if ("B".equals(dto.getCategoryType())) {                categoryDisName = "B_" + dto.getCategoryInName();            }            List<ClassificationDO> classificationDOS = typlmClassificationService.queryClassificationByName(                    categoryDisName);            List<AttributeCardDTO> attributeList = dto.getAttributeList();            String isHiddenModelNumber = dto.getIsHiddenModelNumber();            if (CollUtil.isEmpty(classificationDOS)) {                // 根据品类获取 parentId                String categoryInName = dto.getCategoryInName();                if (categoryInName != null && categoryInName.contains("_")) {                    categoryInName = categoryInName.split("_")[1];                }                if (categoryMap.containsKey(categoryInName)) {                    TyplmClassificationEntityDTO categoryClass = categoryMap.get(categoryInName);                    TyplmClassificationEntityDTO classInfo = null;                    if ("T".equals(dto.getCategoryType())) {                        List<TyplmClassificationEntityDTO> categoryChildClass = this.typlmClassificationService.queryClassification(                                categoryClass.getId());                        Optional<TyplmClassificationEntityDTO> w = categoryChildClass.stream().filter(                                item -> item.getInternalName().startsWith("W_")).findFirst();                        if (w.isPresent()) {                            classInfo = rtClassificationService.createClassAttrCard(dto, w.get().getId(), classRootId);                        } else {                            TyplmClassificationRelentityDTO typlmClassificationRelentityDTO = new TyplmClassificationRelentityDTO();                            typlmClassificationRelentityDTO.setId(categoryClass.getId());                            typlmClassificationRelentityDTO.setRootid(classRootId);                            TyplmClassificationEntityDTO typlmClassificationEntityDTO = new TyplmClassificationEntityDTO();                            typlmClassificationEntityDTO.setInstantiable(1);                            typlmClassificationEntityDTO.setDisplayName(categoryInName + "_物料码");                            typlmClassificationEntityDTO.setInternalName("W_" + categoryInName);                            TyplmClassificationEntityDTO classificationEntityDTO = typlmClassificationService.insertClassification(                                    typlmClassificationEntityDTO, typlmClassificationRelentityDTO);                            classInfo = rtClassificationService.createClassAttrCard(dto,                                                                                    classificationEntityDTO.getId(),                                                                                    classRootId);                        }                    } else {                        classInfo = rtClassificationService.createClassAttrCard(dto, categoryClass.getId(),                                                                                classRootId);                    }                    if (classInfo == null) {                        notFindCategoryList.add(dto);                        errorCategoryName.add(categoryInName);                        return;                    }                    IdentifierEntity classEntity = new IdentifierEntity(new BigInteger(classInfo.getId()),                                                                        classInfo.getOtype());                    //插入属性卡片命中规则                    insertFixCardRules(classInfo, dto);                    if (CollUtil.isNotEmpty(attributeList)) {                        Map<String, AttributeCardDTO> attributeMap = attributeList.stream().filter(Objects::nonNull)                                .filter(item -> item.getAttributeInName() != null).collect(Collectors.toMap(                                        AttributeCardDTO::getAttributeInName,                                        Function.identity(),                                        (oldValue, newValue) -> oldValue));                        //更新描述规则                        updateDescribeRule(attributeList, classEntity, isHiddenModelNumber);                        //创建属性并关联属性                        dealClassIbaAttribute(attributeList, ibaGroupId, classEntity, attributeMap);                        rtClassificationService.updateAttrDefaultValueAndEnum(attributeMap, classEntity, dto,                                                                              enumDiscreteSetConstraintVOS,                                                                              enumGroupId);                    }                } else {                    notFindCategoryList.add(dto);                    errorCategoryName.add(categoryInName);                }                createSuccessList.add(dto);            } else {                // 更新                Map<String, AttributeCardDTO> attributeMap = attributeList.stream().filter(Objects::nonNull)                        .filter(item -> item.getAttributeInName() != null).collect(Collectors.toMap(                                AttributeCardDTO::getAttributeInName,                                Function.identity(),                                (oldValue, newValue) -> oldValue));                dealClassIbaAttribute(attributeList, ibaGroupId, classificationDOS.get(0).getIdentifierRef(), attributeMap);                rtClassificationService.updateAttrDefaultValueAndEnum(attributeMap, classificationDOS.get(0).getIdentifierRef(), dto,                                                                      enumDiscreteSetConstraintVOS,                                                                      enumGroupId);                hsaExictList.add(dto);            }        }        log.info("未找到的品类名称:{}个,未找到的品类名称列表:{}", errorCategoryName.size(), errorCategoryName);        log.info("未找到的品类:{}个,未找到的品类列表:{}", notFindCategoryList.size(), notFindCategoryList);        log.info("总计{}个，创建成功{}个，创建失败:{}个，已存在:{}个", map.size(), createSuccessList.size(), createErrorList.size(), hsaExictList.size());        log.info("创建失败列表:{}", createErrorList);    }    private void dealClassIbaAttribute(List<AttributeCardDTO> attributeList, BigInteger ibaGroupId, IdentifierEntity classEntity, Map<String, AttributeCardDTO> attributeMap) {        List<String> keyNames = attributeList.stream().map(AttributeCardDTO::getAttributeInName).collect(                Collectors.toList());        List<AttributeVO> attributeVOSList = typlmAttributeDefService.queryAttrDefByNameList(keyNames);        Set<String> attributeNames = attributeVOSList.stream().map(AttributeVO::getAttributeDefName).collect(                Collectors.toSet());        attributeList.removeIf(attributeCardDTO -> attributeNames.contains(attributeCardDTO.getAttributeInName()));        //创建iba属性        if (ObjectUtil.isNotEmpty(attributeList)) {            rtAttributeCardService.createIbaAttribute(attributeList, ibaGroupId);        }        List<AttributeVO> attributeVOSList2 = typlmAttributeDefService.queryAttrDefByNameList(keyNames);        //创建iba属性和分类卡片关联关系        rtClassificationService.createClassCardAndAttrLink(attributeVOSList2, attributeMap, classEntity);    }    private void insertFixCardRules(TyplmClassificationEntityDTO classInfo, CategoryAttributeCardDTO dto) {        String categoryType = dto.getCategoryType();        if ("P".equals(categoryType)) {            return;        }        RTAttributeCardDTO rtAttributeCardDTO = new RTAttributeCardDTO();        rtAttributeCardDTO.setAttributeCard(String.valueOf(classInfo.getId()));        rtAttributeCardDTO.setAttributeCardDisplayName(classInfo.getDisplayName());        String categoryInName = dto.getCategoryInName();        if (categoryInName.contains("_")) {            String[] split = categoryInName.split("_");            if (split[0].length() == 1) {                rtAttributeCardDTO.setProductLine(split[0]);            } else {                rtAttributeCardDTO.setProductLine(categoryInName.substring(0, 1));                rtAttributeCardDTO.setDevelopmentOrder(split[0]);            }            rtAttributeCardDTO.setCategory(split[1]);        } else {            rtAttributeCardDTO.setCategory(categoryInName);        }        if (categoryType.equals("T")) {            rtAttributeCardDTO.setType("图样代号");        } else if (categoryType.equals("W")) {            rtAttributeCardDTO.setType("物料码");        } else if (categoryType.equals("B")) {            rtAttributeCardDTO.setType("标准件");        }        rtAttributeCardService.insert(rtAttributeCardDTO);    }    private List<TyplmConstraintRuleDefVO> buildEnumConstraintInfo() {        List<TyplmConstraintRuleDefVO> result = new ArrayList<>();        TyplmConstraintRuleDefVO enumDiscreteSetConstraintVO = new TyplmConstraintRuleDefVO();        enumDiscreteSetConstraintVO.setKey("EnumDiscreteSetConstraint");        enumDiscreteSetConstraintVO.setName("枚举值列表");        enumDiscreteSetConstraintVO.setDataType("枚举值");        enumDiscreteSetConstraintVO.setOid("15818");        enumDiscreteSetConstraintVO.setOtype(TableTypeConstrant.TY_CONSTRAINTRULEDEF_OTYPE);        result.add(enumDiscreteSetConstraintVO);        return result;    }    @Override    public void updateDescribeRule(List<AttributeCardDTO> attributeList,                                   IdentifierEntity entity , String isHiddenModelNumber) {        List<AttributeCardDTO> sortedList = attributeList.stream()                .sorted(Comparator.comparing(AttributeCardDTO::getAttributeNo))                .collect(Collectors.toList());        DescribeSpliceRuleDTO dto = new DescribeSpliceRuleDTO();        StringBuilder disName = new StringBuilder();        StringBuilder inName = new StringBuilder();        if("否".equals(isHiddenModelNumber)){            disName.append("机型_");            inName.append("productType_");        }        for (AttributeCardDTO attributeCardDTO : sortedList) {            String isSplice = attributeCardDTO.getIsSplice();            if("0".equals(isSplice)){                disName.append(attributeCardDTO.getAttributeDisName()).append("_");                inName.append(attributeCardDTO.getAttributeInName()).append("_");            }        }        DescribeSpliceRuleDO describeSpliceRuleDO = rtClassificationService.queryAttrDescribeRule(entity);        if(ObjectUtil.isNotEmpty(describeSpliceRuleDO)){            dto.setOid(String.valueOf(describeSpliceRuleDO.getOid()));        }        dto.setDisplayRules(disName.substring(0, disName.length()-1));        dto.setDescribeRules(inName.substring(0, inName.length()-1));        dto.setClassOid(String.valueOf(entity.getOid()));        dto.setClassOtype(entity.getOtype());        rtClassificationService.saveAttrDescribeRule(dto);    }    @Override    public void batchUpdateDescribeRule(MultipartFile file) {        List<ImportCategoryAttributeCardDTO> categoryAttributeCardDTOS = rtClassificationService.getCategoryAttributeCardDTOS(                file);        Map<String, CategoryAttributeCardDTO> map = CategoryAttributeCardDTO.convert(categoryAttributeCardDTOS);        Set<String> updateErrorList = new HashSet<>();        for (CategoryAttributeCardDTO dto : map.values()) {            String categoryType = dto.getCategoryType();            List<ClassificationDO> classificationDOS = typlmClassificationService.queryClassificationByName(                    categoryType + "_" + dto.getCategoryInName());            if (ObjectUtil.isEmpty(classificationDOS)) {                updateErrorList.add(dto.getCategoryInName());                continue;            }            updateDescribeRule(dto.getAttributeList(), classificationDOS.get(0).getIdentifierRef(),                               dto.getIsHiddenModelNumber());        }        log.info("更新描述规则失败的分类：{}", updateErrorList);    }    @Override    public void batchCreateAttribute(MultipartFile file) {        List<ImportCategoryAttributeCardDTO> categoryAttributeCardDTOS = rtClassificationService.getCategoryAttributeCardDTOS(file);        Map<String, ImportCategoryAttributeCardDTO> attributeToObjectMap = categoryAttributeCardDTOS.stream()                .filter(Objects::nonNull)                .filter(item -> item.getAttributeInName() != null)                .collect(Collectors.toMap(                        ImportCategoryAttributeCardDTO::getAttributeInName,                        Function.identity(),                        (existing, replacement) -> existing                ));//        List<AttributeVO> attributeVOSList = typlmAttributeDefService.queryAttrDefByNameList(new ArrayList<>(attributeToObjectMap.keySet()));//        for (AttributeVO attributeVO : attributeVOSList) {//            attributeToObjectMap.remove(attributeVO.getAttributeDefName());//        }        BigInteger ibaGroupId = rtClassificationMapper.selectIbaGroupId("SXKP");        UserDO user = TyAccountContext.getUser();        //创建iba属性        if (ObjectUtil.isNotEmpty(attributeToObjectMap)) {            for (Map.Entry<String, ImportCategoryAttributeCardDTO> entry : attributeToObjectMap.entrySet()) {                ImportCategoryAttributeCardDTO value = entry.getValue();                AttributeDefDTO attributeDefDTO = new AttributeDefDTO();                attributeDefDTO.setName(entry.getKey());                attributeDefDTO.setAttributegroupoid(ibaGroupId);                attributeDefDTO.setAttributegroupotype(TableTypeConstrant.TY_ATTRIBUTEGROUP_OTYPE);                attributeDefDTO.setDisplayname(value.getAttributeDisName());                attributeDefDTO.setOtype(TableTypeConstrant.TY_STRINGDEF_OTYPE);                typlmAttributeDefService.createAttrDef(attributeDefDTO, user);            }        }    }    @Override    public void updateSpecialPartEnum(MultipartFile file) {        List<ImportSpecialPartDTO> dataList = new ArrayList<>();        try {            dataList = EasyExcel.read(file.getInputStream(), ImportSpecialPartDTO.class,                                      null)                    .sheet()                    .doReadSync();        } catch (Exception e) {            log.error("Excel文件读取失败", e);        }        Map<String, List<ClassInfoDTO>> classInfoDTOMap = new HashMap<>();        List<List<ImportSpecialPartDTO>> dataListList = CommonUtil.subObjectList(dataList, 999);        Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap = new HashMap<>();        Map<BigInteger, List<EnumerationItemHandleVO>> allParentEnumItemMap = new HashMap<>();        for (List<ImportSpecialPartDTO> importPatternCodeDTOS : dataListList) {            List<String> classificationList = importPatternCodeDTOS.stream().map(                            item -> item.getCardType() + "_" + item.getCardName())                    .distinct().collect(Collectors.toList());            Set<BigInteger> classIds = typlmClassificationService.batchQueryClassificationByNameList(classificationList)                    .stream().map(ClassificationDO::getOid).collect(Collectors.toSet());            List<ClassInfoDTO> classInfoDTOList = rtTypeClassMapper.selectClassInfoByClassId(ListUtil.toList(classIds));            Map<String, List<ClassInfoDTO>> classInfoDTOS = classInfoDTOList.stream().collect(                    Collectors.groupingBy(ClassInfoDTO::getClassName, LinkedHashMap::new, Collectors.toList()));            if (CollUtil.isNotEmpty(classInfoDTOS)) {                classInfoDTOMap.putAll(classInfoDTOS);            }            List<List<ClassInfoDTO>> classInfoListList = CommonUtil.subObjectList(classInfoDTOList, 999);            for (List<ClassInfoDTO> classInfoList : classInfoListList) {                Set<String> childEnumIdList = classInfoList.stream().map(ClassInfoDTO::getChildEnumOid).collect(                        Collectors.toSet());                List<EnumerationItemHandleVO> childEnumItemList = enumMapper.batchSelectEnumByEnumId(                        ListUtil.toList(childEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> childEnumItemMap = childEnumItemList.stream().collect(                        Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if (CollUtil.isNotEmpty(childEnumItemMap)) {                    allChildEnumItemMap.putAll(childEnumItemMap);                }                Set<String> parentEnumIdList = classInfoList.stream().map(ClassInfoDTO::getParentEnumOid).collect(                        Collectors.toSet());                List<EnumerationItemHandleVO> parentEnumItemList = enumMapper.batchSelectEnumByEnumId(                        ListUtil.toList(parentEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> parentEnumItemMap = parentEnumItemList.stream().collect(                        Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if (CollUtil.isNotEmpty(parentEnumItemMap)) {                    allParentEnumItemMap.putAll(parentEnumItemMap);                }            }        }        Map<String, List<EnumerationItemHandleVO>> map = new HashMap<>();        Map<String, String> nameAndId = new HashMap<>();        for (ImportSpecialPartDTO dto : dataList) {            if (!classInfoDTOMap.containsKey(dto.getCardType() + "_" + dto.getCardName())) {                continue;            }            log.info("正在处理：{}",dto.getCode());            List<String> ibaAttrName = Arrays.asList(dto.getDescriptionRuleItem().split(";;;"));            List<String> ibaAttrValue = Arrays.asList(dto.getDescriptionRuleValue().split(";;;"));            if (areAllListsEqualSizeStream(ibaAttrValue, ibaAttrName)) {                List<ClassInfoDTO> classInfoDTOS = classInfoDTOMap.get(dto.getCardType() + "_" + dto.getCardName());                Map<String, String> describeRuleDTOS = new HashMap<>();                for (int i = 0; i < ibaAttrValue.size(); i++) {                    describeRuleDTOS.put(ibaAttrName.get(i), ibaAttrValue.get(i));                }                for (ClassInfoDTO classInfoDTO : classInfoDTOS) {                    String attributeDisName = classInfoDTO.getAttributeDisName();                    if(describeRuleDTOS.containsKey(attributeDisName)){                        String value = describeRuleDTOS.get(attributeDisName);                        if(StringUtils.isEmpty(value) || StringUtils.isBlank(value)){                            continue;                        }                        String childEnumOid = classInfoDTO.getChildEnumOid();                        String parentEnumOid = classInfoDTO.getParentEnumOid();                        IdentifierEntity childEnum = new IdentifierEntity();                        childEnum.setOid(new BigInteger(childEnumOid));                        childEnum.setOtype(TableTypeConstrant.CTYOBJECTIDENTIFIER);                        List<EnumerationItemHandleVO> childEnumItems;                        if(allChildEnumItemMap.containsKey(new BigInteger(childEnumOid))){                            childEnumItems = allChildEnumItemMap.get(new BigInteger(childEnumOid));                        }else {                            childEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(childEnum);                        }                        // 在子枚举中查找匹配项                        List<EnumerationItemHandleVO> matchedChildItems = childEnumItems.stream()                                .filter(item -> value.equals(item.getDisplayName()))                                .collect(Collectors.toList());                        // 如果在子枚举中找到匹配项，使用内部名称                        if (CollUtil.isNotEmpty(matchedChildItems)) {                            continue;                        }                        if(parentEnumOid == null){                            if(nameAndId.containsKey(classInfoDTO.getAttributeInName())){                                parentEnumOid = nameAndId.get(classInfoDTO.getAttributeInName());                            }else {                                String attributeInName = classInfoDTO.getAttributeInName();                                if(attributeInName.contains(";;;")){                                    String[] split = attributeInName.split(";;;");                                    attributeInName = split[1];                                }                                List<EnumerationDefDO> parentEnumDefs = typlmEnumerationService.queryEnumDefByNames(                                        Collections.singletonList(attributeInName));                                if(CollUtil.isNotEmpty(parentEnumDefs)){                                    parentEnumOid = parentEnumDefs.get(0).getOid().toString();                                    nameAndId.put(classInfoDTO.getAttributeInName(), parentEnumOid);                                }                            }                        }                        if(parentEnumOid != null){                            IdentifierEntity parentEnum = new IdentifierEntity();                            parentEnum.setOid(new BigInteger(parentEnumOid));                            parentEnum.setOtype(TableTypeConstrant.CTYOBJECTIDENTIFIER);                            List<EnumerationItemHandleVO> parentEnumItems;                            if(allParentEnumItemMap.containsKey(new BigInteger(parentEnumOid))){                                parentEnumItems = allParentEnumItemMap.get(new BigInteger(parentEnumOid));                            }else {                                if(map.containsKey(parentEnumOid)){                                    parentEnumItems = map.get(parentEnumOid);                                }else {                                    parentEnumItems = this.typlmEnumerationItemService.queryEnumerationItemByDefOid(parentEnum);                                    map.put(parentEnumOid, new ArrayList<>());                                }                            }                            // 在父枚举中查找匹配项                            List<EnumerationItemHandleVO> matchedParentItems = parentEnumItems.stream()                                    .filter(item -> value.equals(item.getDisplayName()))                                    .collect(Collectors.toList());                            if (CollUtil.isNotEmpty(matchedParentItems)) {                                // 合并父枚举和子枚举项                                List<EnumerationItemHandleVO> combinedItems = new ArrayList<>(childEnumItems);                                combinedItems.addAll(matchedParentItems);                                // 更新子枚举                                updateEnumItem(combinedItems, new BigInteger(parentEnumOid), new BigInteger(classInfoDTO.getAttributeMapOid()), childEnumOid, false);                            }else {                                List<EnumerationItemHandleVO> combinedItems = new ArrayList<>(childEnumItems);                                EnumerationItemHandleVO newItem = new EnumerationItemHandleVO();                                newItem.setDisplayName(value);                                newItem.setDisplayNameCn(value);                                newItem.setName(value);                                newItem.setState("true");                                newItem.setInternalName(value);                                combinedItems.add(newItem);                                updateEnumItem(combinedItems, new BigInteger(parentEnumOid), new BigInteger(classInfoDTO.getAttributeMapOid()), childEnumOid, false);                            }                        }                    }                }            }        }    }    @Override    public void updateStandPartEnum(MultipartFile file) {        List<ImportStandardPartDTO> dataList = new ArrayList<>();        try {            dataList = EasyExcel.read(file.getInputStream(), ImportStandardPartDTO.class,                                      null)                    .sheet()                    .doReadSync();        } catch (Exception e) {            log.error("Excel文件读取失败", e);        }        Map<String, List<ClassInfoDTO>> classInfoDTOMap = new HashMap<>();        List<List<ImportStandardPartDTO>> dataListList = CommonUtil.subObjectList(dataList, 999);        Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap = new HashMap<>();        Map<BigInteger, List<EnumerationItemHandleVO>> allParentEnumItemMap = new HashMap<>();        for (List<ImportStandardPartDTO> importPatternCodeDTOS : dataListList) {            List<String> classificationList = importPatternCodeDTOS.stream().map(                            item ->  "B_" + item.getPartCode())                    .distinct().collect(Collectors.toList());            Set<BigInteger> classIds = typlmClassificationService.batchQueryClassificationByNameList(classificationList)                    .stream().map(ClassificationDO::getOid).collect(Collectors.toSet());            List<ClassInfoDTO> classInfoDTOList = rtTypeClassMapper.selectClassInfoByClassId(ListUtil.toList(classIds));            Map<String, List<ClassInfoDTO>> classInfoDTOS = classInfoDTOList.stream().collect(                    Collectors.groupingBy(ClassInfoDTO::getClassName, LinkedHashMap::new, Collectors.toList()));            if (CollUtil.isNotEmpty(classInfoDTOS)) {                classInfoDTOMap.putAll(classInfoDTOS);            }            List<List<ClassInfoDTO>> classInfoListList = CommonUtil.subObjectList(classInfoDTOList, 999);            for (List<ClassInfoDTO> classInfoList : classInfoListList) {                Set<String> childEnumIdList = classInfoList.stream().map(ClassInfoDTO::getChildEnumOid).collect(                        Collectors.toSet());                List<EnumerationItemHandleVO> childEnumItemList = enumMapper.batchSelectEnumByEnumId(                        ListUtil.toList(childEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> childEnumItemMap = childEnumItemList.stream().collect(                        Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if (CollUtil.isNotEmpty(childEnumItemMap)) {                    allChildEnumItemMap.putAll(childEnumItemMap);                }                Set<String> parentEnumIdList = classInfoList.stream().map(ClassInfoDTO::getParentEnumOid).collect(                        Collectors.toSet());                List<EnumerationItemHandleVO> parentEnumItemList = enumMapper.batchSelectEnumByEnumId(                        ListUtil.toList(parentEnumIdList));                Map<BigInteger, List<EnumerationItemHandleVO>> parentEnumItemMap = parentEnumItemList.stream().collect(                        Collectors.groupingBy(EnumerationItemHandleVO::getPoid));                if (CollUtil.isNotEmpty(parentEnumItemMap)) {                    allParentEnumItemMap.putAll(parentEnumItemMap);                }            }        }        Map<String, List<ImportStandardPartDTO>> collect = dataList.stream().collect(                Collectors.groupingBy(ImportStandardPartDTO::getPartCode));        for (Map.Entry<String, List<ImportStandardPartDTO>> entry : collect.entrySet()) {            String key = "B_" + entry.getKey();            List<ImportStandardPartDTO> data = entry.getValue();            List<ClassInfoDTO> classInfoDTOS = classInfoDTOMap.get(key);            if (CollUtil.isNotEmpty(classInfoDTOS)) {                for (ClassInfoDTO classInfoDTO : classInfoDTOS) {                    switch (classInfoDTO.getAttributeInName()) {                        case "specification":                            List<String> spec = ListUtil.toList(                                    data.stream()                                            .map(ImportStandardPartDTO::getSpecification)                                            .filter(Objects::nonNull)  // 过滤掉为null的元素                                            .collect(Collectors.toSet())                            );                            updateStandCardEnum(classInfoDTO, allChildEnumItemMap, allParentEnumItemMap, spec);                            break;                        case "specialRequirement":                            List<String> specialRequirement = ListUtil.toList(                                    data.stream().map(ImportStandardPartDTO::getSpecialRequirements).filter(Objects::nonNull)                                            .collect(Collectors.toSet()));                            updateStandCardEnum(classInfoDTO, allChildEnumItemMap, allParentEnumItemMap,                                                specialRequirement);                            break;                        case "screwPitch":                            List<String> pitch = ListUtil.toList(                                    data.stream().map(ImportStandardPartDTO::getPitch).filter(Objects::nonNull) .collect(Collectors.toSet()));                            updateStandCardEnum(classInfoDTO, allChildEnumItemMap, allParentEnumItemMap, pitch);                            break;                        case "performance":                            List<String> performanceLevel = ListUtil.toList(                                    data.stream().map(ImportStandardPartDTO::getPerformanceLevel).filter(Objects::nonNull)                                            .collect(Collectors.toSet()));                            updateStandCardEnum(classInfoDTO, allChildEnumItemMap, allParentEnumItemMap,                                                performanceLevel);                            break;                        case "hazardousSubstance":                            List<String> harmfulSubstances = ListUtil.toList(                                    data.stream().map(ImportStandardPartDTO::getHarmfulSubstances).filter(Objects::nonNull)                                            .collect(Collectors.toSet()));                            updateStandCardEnum(classInfoDTO, allChildEnumItemMap, allParentEnumItemMap,                                                harmfulSubstances);                            break;                        case "surfaceTreatment":                            List<String> surfaceTreatment = ListUtil.toList(                                    data.stream().map(ImportStandardPartDTO::getSurfaceTreatment).filter(Objects::nonNull)                                            .collect(Collectors.toSet()));                            updateStandCardEnum(classInfoDTO, allChildEnumItemMap, allParentEnumItemMap,                                                surfaceTreatment);                            break;                    }                }            }        }    }    private void updateStandCardEnum(ClassInfoDTO classInfoDTO,                           Map<BigInteger, List<EnumerationItemHandleVO>> allChildEnumItemMap,                           Map<BigInteger, List<EnumerationItemHandleVO>> allParentEnumItemMap, List<String> spec) {        if(CollUtil.isEmpty( spec)){            return;        }        List<EnumerationItemHandleVO> allChildEnumItems = allChildEnumItemMap.get(                new BigInteger(classInfoDTO.getChildEnumOid()));        Map<String, EnumerationItemHandleVO> childMap = allChildEnumItemMap.get(                new BigInteger(classInfoDTO.getChildEnumOid())).stream().collect(Collectors.toMap(                        EnumerationItemHandleVO::getName,                        item -> item,                        (v1, v2) -> v1        ));        Map<String, EnumerationItemHandleVO> parentEnumMap = allParentEnumItemMap.get(                new BigInteger(classInfoDTO.getParentEnumOid())).stream().collect(Collectors.toMap(                EnumerationItemHandleVO::getName,                item -> item,                (v1, v2) -> v1        ));        for (String s : spec) {            if(!childMap.containsKey(s)){                if(parentEnumMap.containsKey(s)){                    EnumerationItemHandleVO itemHandleVO = parentEnumMap.get(s);                    allChildEnumItems.add(itemHandleVO);                }            }        }        updateEnumItem(allChildEnumItems, new BigInteger(classInfoDTO.getChildEnumOid()), new BigInteger(classInfoDTO.getAttributeMapOid()), classInfoDTO.getChildEnumOid(), true);    }}